You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by sj...@apache.org on 2022/05/06 17:57:49 UTC

[maven] 01/01: [MNG-7464] Warn about using read-only parameters for Mojo in configuration

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

sjaranowski pushed a commit to branch MNG-7464-3.9
in repository https://gitbox.apache.org/repos/asf/maven.git

commit e62569bb3a952a98be6b4a83d5c202b75dbd3d84
Author: Slawomir Jaranowski <s....@gmail.com>
AuthorDate: Thu Apr 28 21:44:34 2022 +0200

    [MNG-7464] Warn about using read-only parameters for Mojo in configuration
    
    (cherry picked from commit 3dd0afd89772929fa89db974d5bc432846f170de)
---
 ...=> AbstractMavenPluginParametersValidator.java} | 123 ++++++++++-----------
 .../plugin/internal/DefaultMavenPluginManager.java |   9 +-
 .../plugin/internal/DeprecatedPluginValidator.java |  84 +++-----------
 .../ReadOnlyPluginParametersValidator.java         |  85 ++++++++++++++
 4 files changed, 169 insertions(+), 132 deletions(-)

diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
similarity index 53%
copy from maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
copy to maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
index 4c21f80e3..d0fb15db0 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/AbstractMavenPluginParametersValidator.java
@@ -19,68 +19,54 @@ package org.apache.maven.plugin.internal;
  * under the License.
  */
 
-import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import java.util.Arrays;
+import java.util.List;
+
 import org.apache.maven.plugin.descriptor.Parameter;
 import org.apache.maven.shared.utils.logging.MessageBuilder;
 import org.apache.maven.shared.utils.logging.MessageUtils;
-import org.codehaus.plexus.component.annotations.Component;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
- * Print warnings if deprecated mojo or parameters of plugin are used in configuration.
+ * Common implementations for plugin parameters configuration validation.
  *
  * @author Slawomir Jaranowski
  */
-
-@Component( role = MavenPluginConfigurationValidator.class )
-class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
+abstract class AbstractMavenPluginParametersValidator implements MavenPluginConfigurationValidator
 {
-    private static final Logger LOGGER = LoggerFactory.getLogger( DeprecatedPluginValidator.class );
-
-    @Override
-    public void validate( MojoDescriptor mojoDescriptor,
-                          PlexusConfiguration pomConfiguration,
-                          ExpressionEvaluator expressionEvaluator )
-    {
-        if ( !LOGGER.isWarnEnabled() )
-        {
-            return;
-        }
-
-        if ( mojoDescriptor.getDeprecated() != null )
-        {
-            logDeprecatedMojo( mojoDescriptor );
-        }
 
-        if ( mojoDescriptor.getParameters() == null )
-        {
-            return;
-        }
-
-        mojoDescriptor.getParameters().stream()
-            .filter( parameter -> parameter.getDeprecated() != null )
-            .filter( Parameter::isEditable )
-            .forEach( parameter -> checkParameter( parameter, pomConfiguration, expressionEvaluator ) );
-    }
-
-    private static void checkParameter( Parameter parameter,
-                                        PlexusConfiguration pomConfiguration,
-                                        ExpressionEvaluator expressionEvaluator )
-    {
-        PlexusConfiguration config = pomConfiguration.getChild( parameter.getName(), false );
-
-        if ( isValueSet( config, expressionEvaluator ) )
-        {
-            logDeprecatedParameter( parameter );
-        }
-    }
-
-    private static boolean isValueSet( PlexusConfiguration config,
-                                       ExpressionEvaluator expressionEvaluator )
+    // plugin author can provide @Parameter( property = "session" ) in this case property will always evaluate
+    // so, we need ignore those
+
+    // source org.apache.maven.plugin.PluginParameterExpressionEvaluator
+    private static final List<String> IGNORED_PROPERTY_VALUES = Arrays.asList(
+        "basedir",
+        "executedProject",
+        "localRepository",
+        "mojo",
+        "mojoExecution",
+        "plugin",
+        "project",
+        "reactorProjects",
+        "session",
+        "settings"
+    );
+
+    private static final List<String> IGNORED_PROPERTY_PREFIX = Arrays.asList(
+        "mojo.",
+        "plugin.",
+        "project.",
+        "session.",
+        "settings."
+    );
+
+    protected abstract Logger getLogger();
+
+    protected static boolean isValueSet( PlexusConfiguration config,
+                                         ExpressionEvaluator expressionEvaluator )
     {
         if ( config == null )
         {
@@ -100,8 +86,14 @@ class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
             return false;
         }
 
+        if ( isIgnoredProperty( strValue ) )
+        {
+            return false;
+        }
+
         // for declaration like @Parameter( property = "config.property" )
-        // the value will contains ${config.property}
+        // the value will contain ${config.property}
+
         try
         {
             return expressionEvaluator.evaluate( strValue ) != null;
@@ -116,19 +108,26 @@ class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
         return false;
     }
 
-    private void logDeprecatedMojo( MojoDescriptor mojoDescriptor )
+    private static boolean isIgnoredProperty( String strValue )
     {
-        String message = MessageUtils.buffer()
-            .warning( "Goal '" )
-            .warning( mojoDescriptor.getGoal() )
-            .warning( "' is deprecated: " )
-            .warning( mojoDescriptor.getDeprecated() )
-            .toString();
-
-        LOGGER.warn( message );
+        if ( !strValue.startsWith( "${" ) )
+        {
+            return false;
+        }
+
+        String propertyName = strValue.replace( "${", "" ).replace( "}", "" );
+
+        if ( IGNORED_PROPERTY_VALUES.contains( propertyName ) )
+        {
+            return true;
+        }
+
+        return IGNORED_PROPERTY_PREFIX.stream().anyMatch( propertyName::startsWith );
     }
 
-    private static void logDeprecatedParameter( Parameter parameter )
+    protected abstract String getParameterLogReason( Parameter parameter );
+
+    protected void logParameter( Parameter parameter )
     {
         MessageBuilder messageBuilder = MessageUtils.buffer()
             .warning( "Parameter '" )
@@ -145,9 +144,9 @@ class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
         }
 
         messageBuilder
-            .warning( " is deprecated: " )
-            .warning( parameter.getDeprecated() );
+            .warning( " " )
+            .warning( getParameterLogReason( parameter ) );
 
-        LOGGER.warn( messageBuilder.toString() );
+        getLogger().warn( messageBuilder.toString() );
     }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
index 8f00f1659..a69c88eac 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DefaultMavenPluginManager.java
@@ -126,7 +126,7 @@ public class DefaultMavenPluginManager
      * same class realm is used to load build extensions and load mojos for extensions=true plugins.
      * </p>
      * <strong>Note:</strong> This is part of internal implementation and may be changed or removed without notice
-     * 
+     *
      * @since 3.3.0
      */
     public static final String KEY_EXTENSIONS_REALMS = DefaultMavenPluginManager.class.getName() + "/extensionsRealms";
@@ -165,7 +165,7 @@ public class DefaultMavenPluginManager
     private PluginArtifactsCache pluginArtifactsCache;
 
     @Requirement
-    private MavenPluginConfigurationValidator configurationValidator;
+    private List<MavenPluginConfigurationValidator> configurationValidators;
 
     private ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
 
@@ -612,7 +612,10 @@ public class DefaultMavenPluginManager
 
             ExpressionEvaluator expressionEvaluator = new PluginParameterExpressionEvaluator( session, mojoExecution );
 
-            configurationValidator.validate( mojoDescriptor, pomConfiguration, expressionEvaluator );
+            for ( MavenPluginConfigurationValidator validator: configurationValidators )
+            {
+                validator.validate( mojoDescriptor, pomConfiguration, expressionEvaluator );
+            }
 
             populateMojoExecutionFields( mojo, mojoExecution.getExecutionId(), mojoDescriptor, pluginRealm,
                                          pomConfiguration, expressionEvaluator );
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
index 4c21f80e3..5f4af1a9c 100644
--- a/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/DeprecatedPluginValidator.java
@@ -21,10 +21,8 @@ package org.apache.maven.plugin.internal;
 
 import org.apache.maven.plugin.descriptor.MojoDescriptor;
 import org.apache.maven.plugin.descriptor.Parameter;
-import org.apache.maven.shared.utils.logging.MessageBuilder;
 import org.apache.maven.shared.utils.logging.MessageUtils;
 import org.codehaus.plexus.component.annotations.Component;
-import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
 import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
 import org.codehaus.plexus.configuration.PlexusConfiguration;
 import org.slf4j.Logger;
@@ -37,10 +35,22 @@ import org.slf4j.LoggerFactory;
  */
 
 @Component( role = MavenPluginConfigurationValidator.class )
-class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
+class DeprecatedPluginValidator extends AbstractMavenPluginParametersValidator
 {
     private static final Logger LOGGER = LoggerFactory.getLogger( DeprecatedPluginValidator.class );
 
+    @Override
+    protected Logger getLogger()
+    {
+        return LOGGER;
+    }
+
+    @Override
+    protected String getParameterLogReason( Parameter parameter )
+    {
+        return "is deprecated: " + parameter.getDeprecated();
+    }
+
     @Override
     public void validate( MojoDescriptor mojoDescriptor,
                           PlexusConfiguration pomConfiguration,
@@ -67,53 +77,16 @@ class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
             .forEach( parameter -> checkParameter( parameter, pomConfiguration, expressionEvaluator ) );
     }
 
-    private static void checkParameter( Parameter parameter,
-                                        PlexusConfiguration pomConfiguration,
-                                        ExpressionEvaluator expressionEvaluator )
+    private void checkParameter( Parameter parameter,
+                                 PlexusConfiguration pomConfiguration,
+                                 ExpressionEvaluator expressionEvaluator )
     {
         PlexusConfiguration config = pomConfiguration.getChild( parameter.getName(), false );
 
         if ( isValueSet( config, expressionEvaluator ) )
         {
-            logDeprecatedParameter( parameter );
-        }
-    }
-
-    private static boolean isValueSet( PlexusConfiguration config,
-                                       ExpressionEvaluator expressionEvaluator )
-    {
-        if ( config == null )
-        {
-            return false;
-        }
-
-        // there are sub items ... so configuration is declared
-        if ( config.getChildCount() > 0 )
-        {
-            return true;
-        }
-
-        String strValue = config.getValue();
-
-        if ( strValue == null || strValue.isEmpty() )
-        {
-            return false;
+            logParameter( parameter );
         }
-
-        // for declaration like @Parameter( property = "config.property" )
-        // the value will contains ${config.property}
-        try
-        {
-            return expressionEvaluator.evaluate( strValue ) != null;
-        }
-        catch ( ExpressionEvaluationException e )
-        {
-            // not important
-            // will be reported during Mojo fields populate
-        }
-
-        // fallback - in case of error in expressionEvaluator
-        return false;
     }
 
     private void logDeprecatedMojo( MojoDescriptor mojoDescriptor )
@@ -127,27 +100,4 @@ class DeprecatedPluginValidator implements MavenPluginConfigurationValidator
 
         LOGGER.warn( message );
     }
-
-    private static void logDeprecatedParameter( Parameter parameter )
-    {
-        MessageBuilder messageBuilder = MessageUtils.buffer()
-            .warning( "Parameter '" )
-            .warning( parameter.getName() )
-            .warning( '\'' );
-
-        if ( parameter.getExpression() != null )
-        {
-            String userProperty = parameter.getExpression().replace( "${", "'" ).replace( '}', '\'' );
-            messageBuilder
-                .warning( " (user property " )
-                .warning( userProperty )
-                .warning( ")" );
-        }
-
-        messageBuilder
-            .warning( " is deprecated: " )
-            .warning( parameter.getDeprecated() );
-
-        LOGGER.warn( messageBuilder.toString() );
-    }
 }
diff --git a/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java b/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java
new file mode 100644
index 000000000..3165b426e
--- /dev/null
+++ b/maven-core/src/main/java/org/apache/maven/plugin/internal/ReadOnlyPluginParametersValidator.java
@@ -0,0 +1,85 @@
+package org.apache.maven.plugin.internal;
+
+/*
+ * 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.
+ */
+
+import javax.inject.Named;
+import javax.inject.Singleton;
+
+import org.apache.maven.plugin.descriptor.MojoDescriptor;
+import org.apache.maven.plugin.descriptor.Parameter;
+import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
+import org.codehaus.plexus.configuration.PlexusConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Print warnings if read-only parameters of a plugin are used in configuration.
+ *
+ * @author Slawomir Jaranowski
+ */
+@Named
+@Singleton
+public class ReadOnlyPluginParametersValidator extends AbstractMavenPluginParametersValidator
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger( ReadOnlyPluginParametersValidator.class );
+
+    @Override
+    protected Logger getLogger()
+    {
+        return LOGGER;
+    }
+
+    @Override
+    protected String getParameterLogReason( Parameter parameter )
+    {
+        return "is read-only, must not be used in configuration";
+    }
+
+    @Override
+    public void validate( MojoDescriptor mojoDescriptor, PlexusConfiguration pomConfiguration,
+                          ExpressionEvaluator expressionEvaluator )
+    {
+        if ( !LOGGER.isWarnEnabled() )
+        {
+            return;
+        }
+
+        if ( mojoDescriptor.getParameters() == null )
+        {
+            return;
+        }
+
+        mojoDescriptor.getParameters().stream()
+            .filter( parameter -> !parameter.isEditable() )
+            .forEach( parameter -> checkParameter( parameter, pomConfiguration, expressionEvaluator ) );
+    }
+
+    protected void checkParameter( Parameter parameter,
+                                   PlexusConfiguration pomConfiguration,
+                                   ExpressionEvaluator expressionEvaluator )
+    {
+        PlexusConfiguration config = pomConfiguration.getChild( parameter.getName(), false );
+
+        if ( isValueSet( config, expressionEvaluator ) )
+        {
+            logParameter( parameter );
+        }
+    }
+}