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 e9e05ce3..c0983488 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 @@ -62,6 +62,7 @@ import org.apache.maven.plugins.enforcer.utils.EnforcerRuleUtils; import org.apache.maven.plugins.enforcer.utils.PluginWrapper; import org.apache.maven.project.MavenProject; +import org.apache.maven.rtinfo.RuntimeInformation; import org.apache.maven.settings.Settings; import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException; import org.codehaus.plexus.component.repository.exception.ComponentLookupException; @@ -111,6 +112,11 @@ public class RequirePluginVersions */ private boolean banTimestamps = true; + /** + * @since 3.0.0 + */ + private boolean banMavenDefaults = true; + /** * The comma separated list of phases that should be used to find lifecycle plugin bindings. The default value is * "clean,deploy,site". @@ -176,6 +182,8 @@ public class RequirePluginVersions /** The utils. */ private EnforcerRuleUtils utils; + private RuntimeInformation runtimeInformation; + @Override public void execute( EnforcerRuleHelper helper ) throws EnforcerRuleException @@ -190,6 +198,8 @@ public void execute( EnforcerRuleHelper helper ) project = (MavenProject) helper.evaluate( "${project}" ); + runtimeInformation = helper.getComponent( RuntimeInformation.class ); + DefaultLifecycles defaultLifeCycles = helper.getComponent( DefaultLifecycles.class ); lifecycles = defaultLifeCycles.getLifeCycles(); @@ -266,7 +276,8 @@ private void handleMessagesToTheUser( MavenProject project, List failure throws EnforcerRuleException { StringBuilder newMsg = new StringBuilder(); - newMsg.append( "Some plugins are missing valid versions:" ); + newMsg.append( "Some plugins are missing valid versions or depend on Maven " + + runtimeInformation.getMavenVersion() + " defaults:" ); handleBanMessages( newMsg ); newMsg.append( "\n" ); for ( Plugin plugin : failures ) @@ -281,13 +292,27 @@ private void handleMessagesToTheUser( MavenProject project, List failure Plugin currentPlugin = findCurrentPlugin( plugin, project ); - if ( currentPlugin != null ) + if ( currentPlugin == null ) { - newMsg.append( currentPlugin.getVersion() ); + newMsg.append( "unknown" ); } else { - newMsg.append( "unknown" ); + newMsg.append( currentPlugin.getVersion() ); + + if ( PluginWrapper.isVersionFromDefaultLifecycleBindings( currentPlugin ).orElse( false ) ) + { + newMsg.append( " via default lifecycle bindings" ); + } + else + { + String msg = PluginWrapper.isVersionFromSuperpom( currentPlugin ) + .filter( b -> b ) + .map( t -> " via super POM" ) + // for Maven 3.6.0 or before (MNG-6593 / MNG-6600) + .orElse( " via super POM or default lifecycle bindings" ); + newMsg.append( msg ); + } } } catch ( Exception e ) @@ -966,7 +991,7 @@ private void getProfilePluginManagementPlugins( List plugins, Mod try { List modelPlugins = profile.getBuild().getPluginManagement().getPlugins(); - plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), banMavenDefaults ) ); } catch ( NullPointerException e ) { @@ -980,7 +1005,8 @@ private void getProfileReportingPlugins( List plugins, Model mode { List modelReportPlugins = profile.getReporting().getPlugins(); // add the reporting plugins - plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ), + banMavenDefaults ) ); } catch ( NullPointerException e ) { @@ -993,7 +1019,7 @@ private void getProfilePlugins( List plugins, Model model, Profil try { List modelPlugins = profile.getBuild().getPlugins(); - plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), banMavenDefaults ) ); } catch ( NullPointerException e ) { @@ -1006,7 +1032,7 @@ private void getPlugins( List plugins, Model model ) try { List modelPlugins = model.getBuild().getPlugins(); - plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), banMavenDefaults ) ); } catch ( NullPointerException e ) { @@ -1019,7 +1045,7 @@ private void getPluginManagementPlugins( List plugins, Model mode try { List modelPlugins = model.getBuild().getPluginManagement().getPlugins(); - plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolvePlugins( modelPlugins ), banMavenDefaults ) ); } catch ( NullPointerException e ) { @@ -1033,7 +1059,8 @@ private void getReportingPlugins( List plugins, Model model ) { List modelReportPlugins = model.getReporting().getPlugins(); // add the reporting plugins - plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ) ) ); + plugins.addAll( PluginWrapper.addAll( utils.resolveReportPlugins( modelReportPlugins ), + banMavenDefaults ) ); } catch ( NullPointerException e ) { diff --git a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/PluginWrapper.java b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/PluginWrapper.java index b02befa0..70d2f114 100644 --- a/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/PluginWrapper.java +++ b/enforcer-rules/src/main/java/org/apache/maven/plugins/enforcer/utils/PluginWrapper.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; import org.apache.maven.model.InputLocation; import org.apache.maven.model.InputLocationTracker; @@ -41,15 +42,22 @@ public class PluginWrapper private final InputLocationTracker locationTracker; - public static List addAll( List plugins ) + public static List addAll( List plugins, boolean banMavenDefaults ) { List results = null; if ( !plugins.isEmpty() ) { results = new ArrayList<>( plugins.size() ); - for ( Object o : plugins ) + for ( InputLocationTracker o : plugins ) { + // null or true means it is most assumed a Maven default + if ( banMavenDefaults && ( isVersionFromDefaultLifecycleBindings( o ).orElse( true ) + || isVersionFromSuperpom( o ).orElse( true ) ) ) + { + continue; + } + if ( o instanceof Plugin ) { results.add( new PluginWrapper( (Plugin) o ) ); @@ -61,11 +69,46 @@ public static List addAll( List plugins ) results.add( new PluginWrapper( (ReportPlugin) o ) ); } } - } } return results; } + + /** + * + * @param o either Plugin or ReportPlugin + * @return + */ + public static Optional isVersionFromDefaultLifecycleBindings( InputLocationTracker o ) + { + InputLocation versionLocation = o.getLocation( "version" ); + if ( versionLocation == null ) + { + return Optional.empty(); + } + + String modelId = versionLocation.getSource().getModelId(); + return Optional.of( modelId.startsWith( "org.apache.maven:maven-core:" ) + && modelId.endsWith( ":default-lifecycle-bindings" ) ); + } + + /** + * + * @param o either Plugin or ReportPlugin + * @return null if untraceable, otherwise its matching value + */ + public static Optional isVersionFromSuperpom( InputLocationTracker o ) + { + InputLocation versionLocation = o.getLocation( "version" ); + if ( versionLocation == null ) + { + return Optional.empty(); + } + + String modelId = versionLocation.getSource().getModelId(); + return Optional.of( modelId.startsWith( "org.apache.maven:maven-model-builder:" ) + && modelId.endsWith( ":super-pom" ) ); + } private PluginWrapper( Plugin plugin ) { diff --git a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/EnforcerTestUtils.java b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/EnforcerTestUtils.java index 006a729b..792c82d6 100644 --- a/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/EnforcerTestUtils.java +++ b/enforcer-rules/src/test/java/org/apache/maven/plugins/enforcer/EnforcerTestUtils.java @@ -34,6 +34,8 @@ import org.apache.maven.execution.MavenExecutionRequest; import org.apache.maven.execution.MavenExecutionResult; import org.apache.maven.execution.MavenSession; +import org.apache.maven.model.InputLocation; +import org.apache.maven.model.InputSource; import org.apache.maven.model.Plugin; import org.apache.maven.plugin.MojoExecution; import org.apache.maven.plugin.PluginParameterExpressionEvaluator; @@ -189,10 +191,14 @@ public static EnforcerRuleHelper getHelper( MavenProject project, ExpressionEval */ public static Plugin newPlugin( String groupId, String artifactId, String version ) { + InputSource inputSource = new InputSource(); + inputSource.setModelId( "unit" ); + Plugin plugin = new Plugin(); plugin.setArtifactId( artifactId ); plugin.setGroupId( groupId ); plugin.setVersion( version ); + plugin.setLocation( "version", new InputLocation( 0, 0, inputSource ) ); return plugin; } } 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 c2947ad5..8f85c5f3 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,7 +80,7 @@ public void testHasVersionSpecified() plugins.add( EnforcerTestUtils.newPlugin( "group", "g-artifact", "1.0-12345678.123456-1" ) ); - List pluginWrappers = PluginWrapper.addAll( plugins ); + List pluginWrappers = PluginWrapper.addAll( plugins, false ); RequirePluginVersions rule = new RequirePluginVersions(); rule.setBanLatest( false ); @@ -145,7 +145,7 @@ public void testHasVersionSpecifiedWithProperties() plugins.add( EnforcerTestUtils.newPlugin( "group", "e-artifact", "${}" ) ); plugins.add( EnforcerTestUtils.newPlugin( "group", "f-artifact", "${ }" ) ); - List pluginWrappers = PluginWrapper.addAll( plugins ); + List pluginWrappers = PluginWrapper.addAll( plugins, false ); RequirePluginVersions rule = new RequirePluginVersions(); rule.setBanLatest( false ); diff --git a/maven-enforcer-plugin/src/it/mrm/repository/menforcer359-1.0.pom b/maven-enforcer-plugin/src/it/mrm/repository/menforcer359-1.0.pom index 38b9e012..df05e312 100644 --- a/maven-enforcer-plugin/src/it/mrm/repository/menforcer359-1.0.pom +++ b/maven-enforcer-plugin/src/it/mrm/repository/menforcer359-1.0.pom @@ -23,6 +23,7 @@ org.apache.maven.plugins.enforcer.its menforcer359 1.0 + pom diff --git a/maven-enforcer-plugin/src/it/projects/require-plugin-versions-ci/verify.groovy b/maven-enforcer-plugin/src/it/projects/require-plugin-versions-ci/verify.groovy index d0989172..574942ca 100644 --- a/maven-enforcer-plugin/src/it/projects/require-plugin-versions-ci/verify.groovy +++ b/maven-enforcer-plugin/src/it/projects/require-plugin-versions-ci/verify.groovy @@ -18,4 +18,4 @@ */ File buildLog = new File( basedir, 'build.log' ) assert buildLog.text.contains( '[WARNING] Rule 0: org.apache.maven.plugins.enforcer.RequirePluginVersions failed with message:' ) -assert buildLog.text.contains( 'Some plugins are missing valid versions: (LATEST RELEASE SNAPSHOT are not allowed)' ) +assert buildLog.text.contains( "Some plugins are missing valid versions or depend on Maven ${mavenVersion} defaults: (LATEST RELEASE SNAPSHOT are not allowed)" ) diff --git a/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/invoker.properties b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/invoker.properties new file mode 100644 index 00000000..c98ac4c5 --- /dev/null +++ b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/invoker.properties @@ -0,0 +1,18 @@ +# 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. + +invoker.buildResult=failure \ No newline at end of file diff --git a/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/pom.xml b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/pom.xml new file mode 100644 index 00000000..72bef8b4 --- /dev/null +++ b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_failure/pom.xml @@ -0,0 +1,57 @@ + + + + + + 4.0.0 + + org.apache.maven.its.enforcer + test + 1.0 + pom + + + + + + + + org.apache.maven.plugins + maven-enforcer-plugin + @project.version@ + + + test + + enforce + + + + + false + + + + + + + + + diff --git a/maven-enforcer-plugin/src/it/projects/require-plugin-versions_inherit/pom.xml b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_inherit/pom.xml index 6208ba20..c049b331 100644 --- a/maven-enforcer-plugin/src/it/projects/require-plugin-versions_inherit/pom.xml +++ b/maven-enforcer-plugin/src/it/projects/require-plugin-versions_inherit/pom.xml @@ -22,6 +22,12 @@ under the License. 4.0.0 + + org.apache.maven.plugins.enforcer.its + menforcer359 + 1.0 + + org.apache.maven.its.enforcer test 1.0