mirror of https://github.com/apache/maven.git
[MNG-7754] Improvement and extension of plugin validation (#1079)
This is general rework of current Maven 3.9.x line how it handles plugin and mojo validations. Changes: * added plugin validations for dependencies * introduced pluginValidationManager that gathers violations * manager creates a report at build end, with dense and non repeating data * this is in spirit to lessen already too verbose logging, as current solution would report violations as many times plugin is used in reactor, and that can be many (ie. a plugin from parent for each module) Example report of Maven 3.9.x build: https://gist.github.com/cstamas/b62fdcd53eaf316123cf183f5a24e6a5 --- https://issues.apache.org/jira/browse/MNG-7754
This commit is contained in:
parent
b2ee29e03e
commit
53b6473237
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
import org.eclipse.aether.RepositorySystemSession;
|
||||||
|
import org.eclipse.aether.artifact.Artifact;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Component collecting plugin validation issues and reporting them.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
public interface PluginValidationManager {
|
||||||
|
/**
|
||||||
|
* Reports plugin issues applicable to the plugin as a whole.
|
||||||
|
* <p>
|
||||||
|
* This method should be used in "early" phase of plugin execution, possibly even when plugin or mojo descriptor
|
||||||
|
* does not exist yet. In turn, this method will not record extra information like plugin occurrence or declaration
|
||||||
|
* location as those are not yet available.
|
||||||
|
*/
|
||||||
|
void reportPluginValidationIssue(RepositorySystemSession session, Artifact pluginArtifact, String issue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports plugin issues applicable to the plugin as a whole.
|
||||||
|
* <p>
|
||||||
|
* This method will record extra information as well, like plugin occurrence or declaration location.
|
||||||
|
*/
|
||||||
|
void reportPluginValidationIssue(MavenSession mavenSession, MojoDescriptor mojoDescriptor, String issue);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reports plugin Mojo issues applicable to the Mojo itself.
|
||||||
|
* <p>
|
||||||
|
* This method will record extra information as well, like plugin occurrence or declaration location.
|
||||||
|
*/
|
||||||
|
void reportPluginMojoValidationIssue(
|
||||||
|
MavenSession mavenSession, MojoDescriptor mojoDescriptor, Class<?> mojoClass, String issue);
|
||||||
|
}
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
|
||||||
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service responsible for validating plugin dependencies.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
abstract class AbstractMavenPluginDependenciesValidator implements MavenPluginDependenciesValidator {
|
||||||
|
|
||||||
|
protected final List<String> expectedProvidedScopeExclusions = Arrays.asList(
|
||||||
|
"org.apache.maven:maven-archiver", "org.apache.maven:maven-jxr", "org.apache.maven:plexus-utils");
|
||||||
|
|
||||||
|
protected final PluginValidationManager pluginValidationManager;
|
||||||
|
|
||||||
|
protected AbstractMavenPluginDependenciesValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
this.pluginValidationManager = requireNonNull(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void validate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
if (mojoDescriptor.getPluginDescriptor() != null
|
||||||
|
&& mojoDescriptor.getPluginDescriptor().getDependencies() != null) {
|
||||||
|
doValidate(mavenSession, mojoDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor);
|
||||||
|
}
|
|
@ -21,6 +21,8 @@ package org.apache.maven.plugin.internal;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common implementations for plugin parameters configuration validation that relies on Mojo descriptor (leaves out
|
* Common implementations for plugin parameters configuration validation that relies on Mojo descriptor (leaves out
|
||||||
* core parameters by default).
|
* core parameters by default).
|
||||||
|
@ -48,6 +50,10 @@ abstract class AbstractMavenPluginDescriptorSourcedParametersValidator extends A
|
||||||
private static final List<String> IGNORED_PROPERTY_PREFIX =
|
private static final List<String> IGNORED_PROPERTY_PREFIX =
|
||||||
Arrays.asList("mojo.", "pom.", "plugin.", "project.", "session.", "settings.");
|
Arrays.asList("mojo.", "pom.", "plugin.", "project.", "session.", "settings.");
|
||||||
|
|
||||||
|
protected AbstractMavenPluginDescriptorSourcedParametersValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean isIgnoredProperty(String strValue) {
|
protected boolean isIgnoredProperty(String strValue) {
|
||||||
if (!strValue.startsWith("${")) {
|
if (!strValue.startsWith("${")) {
|
||||||
|
|
|
@ -18,15 +18,15 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.maven.plugin.internal;
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.apache.maven.plugin.descriptor.Parameter;
|
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.configurator.expression.ExpressionEvaluationException;
|
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluationException;
|
||||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
||||||
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
import static java.util.Objects.requireNonNull;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common implementations for plugin parameters configuration validation.
|
* Common implementations for plugin parameters configuration validation.
|
||||||
|
@ -35,7 +35,11 @@ import org.slf4j.LoggerFactory;
|
||||||
*/
|
*/
|
||||||
abstract class AbstractMavenPluginParametersValidator implements MavenPluginConfigurationValidator {
|
abstract class AbstractMavenPluginParametersValidator implements MavenPluginConfigurationValidator {
|
||||||
|
|
||||||
protected final Logger logger = LoggerFactory.getLogger(getClass());
|
protected final PluginValidationManager pluginValidationManager;
|
||||||
|
|
||||||
|
protected AbstractMavenPluginParametersValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
this.pluginValidationManager = requireNonNull(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isValueSet(PlexusConfiguration config, ExpressionEvaluator expressionEvaluator) {
|
protected boolean isValueSet(PlexusConfiguration config, ExpressionEvaluator expressionEvaluator) {
|
||||||
if (config == null) {
|
if (config == null) {
|
||||||
|
@ -73,18 +77,18 @@ abstract class AbstractMavenPluginParametersValidator implements MavenPluginConf
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public final void validate(
|
public final void validate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator) {
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
if (!logger.isWarnEnabled()) {
|
doValidate(mavenSession, mojoDescriptor, mojoClass, pomConfiguration, expressionEvaluator);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
doValidate(mojoDescriptor, pomConfiguration, expressionEvaluator);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void doValidate(
|
protected abstract void doValidate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator);
|
ExpressionEvaluator expressionEvaluator);
|
||||||
|
|
||||||
|
@ -94,19 +98,19 @@ abstract class AbstractMavenPluginParametersValidator implements MavenPluginConf
|
||||||
|
|
||||||
protected abstract String getParameterLogReason(Parameter parameter);
|
protected abstract String getParameterLogReason(Parameter parameter);
|
||||||
|
|
||||||
protected void logParameter(Parameter parameter) {
|
protected String formatParameter(Parameter parameter) {
|
||||||
MessageBuilder messageBuilder = MessageUtils.buffer()
|
StringBuilder stringBuilder = new StringBuilder()
|
||||||
.warning("Parameter '")
|
.append("Parameter '")
|
||||||
.warning(parameter.getName())
|
.append(parameter.getName())
|
||||||
.warning('\'');
|
.append('\'');
|
||||||
|
|
||||||
if (parameter.getExpression() != null) {
|
if (parameter.getExpression() != null) {
|
||||||
String userProperty = parameter.getExpression().replace("${", "'").replace('}', '\'');
|
String userProperty = parameter.getExpression().replace("${", "'").replace('}', '\'');
|
||||||
messageBuilder.warning(" (user property ").warning(userProperty).warning(")");
|
stringBuilder.append(" (user property ").append(userProperty).append(")");
|
||||||
}
|
}
|
||||||
|
|
||||||
messageBuilder.warning(" ").warning(getParameterLogReason(parameter));
|
stringBuilder.append(" ").append(getParameterLogReason(parameter));
|
||||||
|
|
||||||
logger.warn(messageBuilder.toString());
|
return stringBuilder.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,6 +71,7 @@ import org.apache.maven.plugin.PluginParameterExpressionEvaluator;
|
||||||
import org.apache.maven.plugin.PluginParameterExpressionEvaluatorV4;
|
import org.apache.maven.plugin.PluginParameterExpressionEvaluatorV4;
|
||||||
import org.apache.maven.plugin.PluginRealmCache;
|
import org.apache.maven.plugin.PluginRealmCache;
|
||||||
import org.apache.maven.plugin.PluginResolutionException;
|
import org.apache.maven.plugin.PluginResolutionException;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.apache.maven.plugin.descriptor.Parameter;
|
import org.apache.maven.plugin.descriptor.Parameter;
|
||||||
import org.apache.maven.plugin.descriptor.PluginDescriptor;
|
import org.apache.maven.plugin.descriptor.PluginDescriptor;
|
||||||
|
@ -99,6 +100,7 @@ import org.codehaus.plexus.component.repository.exception.ComponentLookupExcepti
|
||||||
import org.codehaus.plexus.configuration.DefaultPlexusConfiguration;
|
import org.codehaus.plexus.configuration.DefaultPlexusConfiguration;
|
||||||
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
import org.codehaus.plexus.configuration.PlexusConfigurationException;
|
import org.codehaus.plexus.configuration.PlexusConfigurationException;
|
||||||
|
import org.codehaus.plexus.personality.plexus.lifecycle.phase.Contextualizable;
|
||||||
import org.codehaus.plexus.util.ReaderFactory;
|
import org.codehaus.plexus.util.ReaderFactory;
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
import org.codehaus.plexus.util.StringUtils;
|
||||||
import org.eclipse.aether.RepositorySystemSession;
|
import org.eclipse.aether.RepositorySystemSession;
|
||||||
|
@ -146,8 +148,9 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
|
||||||
private PluginArtifactsCache pluginArtifactsCache;
|
private PluginArtifactsCache pluginArtifactsCache;
|
||||||
private MavenPluginValidator pluginValidator;
|
private MavenPluginValidator pluginValidator;
|
||||||
private List<MavenPluginConfigurationValidator> configurationValidators;
|
private List<MavenPluginConfigurationValidator> configurationValidators;
|
||||||
|
private List<MavenPluginDependenciesValidator> dependenciesValidators;
|
||||||
|
private PluginValidationManager pluginValidationManager;
|
||||||
private List<MavenPluginPrerequisitesChecker> prerequisitesCheckers;
|
private List<MavenPluginPrerequisitesChecker> prerequisitesCheckers;
|
||||||
|
|
||||||
private final ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
|
private final ExtensionDescriptorBuilder extensionDescriptorBuilder = new ExtensionDescriptorBuilder();
|
||||||
private final PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
|
private final PluginDescriptorBuilder builder = new PluginDescriptorBuilder();
|
||||||
|
|
||||||
|
@ -165,6 +168,8 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
|
||||||
PluginArtifactsCache pluginArtifactsCache,
|
PluginArtifactsCache pluginArtifactsCache,
|
||||||
MavenPluginValidator pluginValidator,
|
MavenPluginValidator pluginValidator,
|
||||||
List<MavenPluginConfigurationValidator> configurationValidators,
|
List<MavenPluginConfigurationValidator> configurationValidators,
|
||||||
|
List<MavenPluginDependenciesValidator> dependencyValidators,
|
||||||
|
PluginValidationManager pluginValidationManager,
|
||||||
List<MavenPluginPrerequisitesChecker> prerequisitesCheckers) {
|
List<MavenPluginPrerequisitesChecker> prerequisitesCheckers) {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.classRealmManager = classRealmManager;
|
this.classRealmManager = classRealmManager;
|
||||||
|
@ -177,6 +182,8 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
|
||||||
this.pluginArtifactsCache = pluginArtifactsCache;
|
this.pluginArtifactsCache = pluginArtifactsCache;
|
||||||
this.pluginValidator = pluginValidator;
|
this.pluginValidator = pluginValidator;
|
||||||
this.configurationValidators = configurationValidators;
|
this.configurationValidators = configurationValidators;
|
||||||
|
this.dependenciesValidators = dependencyValidators;
|
||||||
|
this.pluginValidationManager = pluginValidationManager;
|
||||||
this.prerequisitesCheckers = prerequisitesCheckers;
|
this.prerequisitesCheckers = prerequisitesCheckers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -559,6 +566,18 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
|
||||||
((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
|
((Mojo) mojo).setLog(new MojoLogWrapper(mojoLogger));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mojo instanceof Contextualizable) {
|
||||||
|
pluginValidationManager.reportPluginMojoValidationIssue(
|
||||||
|
session,
|
||||||
|
mojoDescriptor,
|
||||||
|
mojo.getClass(),
|
||||||
|
"Implements `Contextualizable` interface from Plexus Container, which is EOL.");
|
||||||
|
}
|
||||||
|
|
||||||
|
for (MavenPluginDependenciesValidator validator : dependenciesValidators) {
|
||||||
|
validator.validate(session, mojoDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
XmlNode dom = mojoExecution.getConfiguration() != null
|
XmlNode dom = mojoExecution.getConfiguration() != null
|
||||||
? mojoExecution.getConfiguration().getDom()
|
? mojoExecution.getConfiguration().getDom()
|
||||||
: null;
|
: null;
|
||||||
|
@ -582,7 +601,7 @@ public class DefaultMavenPluginManager implements MavenPluginManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (MavenPluginConfigurationValidator validator : configurationValidators) {
|
for (MavenPluginConfigurationValidator validator : configurationValidators) {
|
||||||
validator.validate(mojoDescriptor, pomConfiguration, expressionEvaluator);
|
validator.validate(session, mojoDescriptor, mojo.getClass(), pomConfiguration, expressionEvaluator);
|
||||||
}
|
}
|
||||||
|
|
||||||
populateMojoExecutionFields(
|
populateMojoExecutionFields(
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.apache.maven.RepositoryUtils;
|
||||||
import org.apache.maven.model.Dependency;
|
import org.apache.maven.model.Dependency;
|
||||||
import org.apache.maven.model.Plugin;
|
import org.apache.maven.model.Plugin;
|
||||||
import org.apache.maven.plugin.PluginResolutionException;
|
import org.apache.maven.plugin.PluginResolutionException;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
import org.codehaus.plexus.util.StringUtils;
|
||||||
import org.eclipse.aether.DefaultRepositorySystemSession;
|
import org.eclipse.aether.DefaultRepositorySystemSession;
|
||||||
import org.eclipse.aether.RepositorySystem;
|
import org.eclipse.aether.RepositorySystem;
|
||||||
|
@ -77,9 +78,13 @@ public class DefaultPluginDependenciesResolver implements PluginDependenciesReso
|
||||||
|
|
||||||
private final RepositorySystem repoSystem;
|
private final RepositorySystem repoSystem;
|
||||||
|
|
||||||
|
private final PluginValidationManager pluginValidationManager;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
public DefaultPluginDependenciesResolver(RepositorySystem repoSystem) {
|
public DefaultPluginDependenciesResolver(
|
||||||
|
RepositorySystem repoSystem, PluginValidationManager pluginValidationManager) {
|
||||||
this.repoSystem = repoSystem;
|
this.repoSystem = repoSystem;
|
||||||
|
this.pluginValidationManager = pluginValidationManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
|
private Artifact toArtifact(Plugin plugin, RepositorySystemSession session) {
|
||||||
|
@ -107,6 +112,19 @@ public class DefaultPluginDependenciesResolver implements PluginDependenciesReso
|
||||||
request.setTrace(trace);
|
request.setTrace(trace);
|
||||||
ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
|
ArtifactDescriptorResult result = repoSystem.readArtifactDescriptor(pluginSession, request);
|
||||||
|
|
||||||
|
if (result.getDependencies() != null) {
|
||||||
|
for (org.eclipse.aether.graph.Dependency dependency : result.getDependencies()) {
|
||||||
|
if ("org.apache.maven".equals(dependency.getArtifact().getGroupId())
|
||||||
|
&& "maven-compat".equals(dependency.getArtifact().getArtifactId())
|
||||||
|
&& !JavaScopes.TEST.equals(dependency.getScope())) {
|
||||||
|
pluginValidationManager.reportPluginValidationIssue(
|
||||||
|
session,
|
||||||
|
pluginArtifact,
|
||||||
|
"Plugin depends on the deprecated Maven 2.x compatibility layer, which may not be supported in Maven 4.x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pluginArtifact = result.getArtifact();
|
pluginArtifact = result.getArtifact();
|
||||||
|
|
||||||
if (logger.isWarnEnabled()) {
|
if (logger.isWarnEnabled()) {
|
||||||
|
|
|
@ -0,0 +1,270 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.Locale;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.apache.maven.AbstractMavenLifecycleParticipant;
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.model.InputLocation;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
import org.apache.maven.plugin.descriptor.PluginDescriptor;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.eclipse.aether.RepositorySystemSession;
|
||||||
|
import org.eclipse.aether.artifact.Artifact;
|
||||||
|
import org.eclipse.aether.util.ConfigUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
@Named
|
||||||
|
public final class DefaultPluginValidationManager extends AbstractMavenLifecycleParticipant
|
||||||
|
implements PluginValidationManager {
|
||||||
|
|
||||||
|
private static final String ISSUES_KEY = DefaultPluginValidationManager.class.getName() + ".issues";
|
||||||
|
|
||||||
|
private static final String MAVEN_PLUGIN_VALIDATION_KEY = "maven.plugin.validation";
|
||||||
|
|
||||||
|
private enum ValidationLevel {
|
||||||
|
DISABLED,
|
||||||
|
ENABLED,
|
||||||
|
VERBOSE
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(getClass());
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void afterSessionEnd(MavenSession session) {
|
||||||
|
reportSessionCollectedValidationIssues(session);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ValidationLevel validationLevel(RepositorySystemSession session) {
|
||||||
|
String level = ConfigUtils.getString(session, null, MAVEN_PLUGIN_VALIDATION_KEY);
|
||||||
|
if (level == null || level.isEmpty()) {
|
||||||
|
return ValidationLevel.ENABLED;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
return ValidationLevel.valueOf(level.toUpperCase(Locale.ENGLISH));
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
logger.warn(
|
||||||
|
"Invalid value specified for property {}: '{}'. Supported values are (case insensitive): {}",
|
||||||
|
MAVEN_PLUGIN_VALIDATION_KEY,
|
||||||
|
level,
|
||||||
|
Arrays.toString(ValidationLevel.values()));
|
||||||
|
return ValidationLevel.ENABLED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pluginKey(String groupId, String artifactId, String version) {
|
||||||
|
return groupId + ":" + artifactId + ":" + version;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pluginKey(MojoDescriptor mojoDescriptor) {
|
||||||
|
PluginDescriptor pd = mojoDescriptor.getPluginDescriptor();
|
||||||
|
return pluginKey(pd.getGroupId(), pd.getArtifactId(), pd.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pluginKey(Artifact pluginArtifact) {
|
||||||
|
return pluginKey(pluginArtifact.getGroupId(), pluginArtifact.getArtifactId(), pluginArtifact.getVersion());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportPluginValidationIssue(RepositorySystemSession session, Artifact pluginArtifact, String issue) {
|
||||||
|
String pluginKey = pluginKey(pluginArtifact);
|
||||||
|
PluginValidationIssues pluginIssues =
|
||||||
|
pluginIssues(session).computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
|
||||||
|
pluginIssues.reportPluginIssue(null, null, issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportPluginValidationIssue(MavenSession mavenSession, MojoDescriptor mojoDescriptor, String issue) {
|
||||||
|
String pluginKey = pluginKey(mojoDescriptor);
|
||||||
|
PluginValidationIssues pluginIssues = pluginIssues(mavenSession.getRepositorySession())
|
||||||
|
.computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
|
||||||
|
pluginIssues.reportPluginIssue(
|
||||||
|
pluginDeclaration(mavenSession, mojoDescriptor), pluginOccurrence(mavenSession), issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reportPluginMojoValidationIssue(
|
||||||
|
MavenSession mavenSession, MojoDescriptor mojoDescriptor, Class<?> mojoClass, String issue) {
|
||||||
|
String pluginKey = pluginKey(mojoDescriptor);
|
||||||
|
PluginValidationIssues pluginIssues = pluginIssues(mavenSession.getRepositorySession())
|
||||||
|
.computeIfAbsent(pluginKey, k -> new PluginValidationIssues());
|
||||||
|
pluginIssues.reportPluginMojoIssue(
|
||||||
|
pluginDeclaration(mavenSession, mojoDescriptor),
|
||||||
|
pluginOccurrence(mavenSession),
|
||||||
|
mojoInfo(mojoDescriptor, mojoClass),
|
||||||
|
issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void reportSessionCollectedValidationIssues(MavenSession mavenSession) {
|
||||||
|
ValidationLevel validationLevel = validationLevel(mavenSession.getRepositorySession());
|
||||||
|
ConcurrentHashMap<String, PluginValidationIssues> issuesMap = pluginIssues(mavenSession.getRepositorySession());
|
||||||
|
if (!issuesMap.isEmpty()) {
|
||||||
|
|
||||||
|
logger.warn("");
|
||||||
|
logger.warn("Plugin validation issues were detected in {} plugin(s)", issuesMap.size());
|
||||||
|
logger.warn("");
|
||||||
|
if (validationLevel == ValidationLevel.DISABLED || !logger.isWarnEnabled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Map.Entry<String, PluginValidationIssues> entry : issuesMap.entrySet()) {
|
||||||
|
logger.warn("Plugin {}", entry.getKey());
|
||||||
|
PluginValidationIssues issues = entry.getValue();
|
||||||
|
if (validationLevel == ValidationLevel.VERBOSE && !issues.pluginDeclarations.isEmpty()) {
|
||||||
|
logger.warn(" Declared at location(s):");
|
||||||
|
for (String pluginDeclaration : issues.pluginDeclarations) {
|
||||||
|
logger.warn(" * {}", pluginDeclaration);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (validationLevel == ValidationLevel.VERBOSE && !issues.pluginOccurrences.isEmpty()) {
|
||||||
|
logger.warn(" Used in module(s):");
|
||||||
|
for (String pluginOccurrence : issues.pluginOccurrences) {
|
||||||
|
logger.warn(" * {}", pluginOccurrence);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!issues.pluginIssues.isEmpty()) {
|
||||||
|
logger.warn(" Plugin issue(s):");
|
||||||
|
for (String pluginIssue : issues.pluginIssues) {
|
||||||
|
logger.warn(" * {}", pluginIssue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!issues.mojoIssues.isEmpty()) {
|
||||||
|
logger.warn(" Mojo issue(s):");
|
||||||
|
for (String mojoInfo : issues.mojoIssues.keySet()) {
|
||||||
|
logger.warn(" * Mojo {}", mojoInfo);
|
||||||
|
for (String mojoIssue : issues.mojoIssues.get(mojoInfo)) {
|
||||||
|
logger.warn(" - {}", mojoIssue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
logger.warn("");
|
||||||
|
}
|
||||||
|
logger.warn("");
|
||||||
|
logger.warn(
|
||||||
|
"To fix these issues, please upgrade above listed plugins, or, notify their maintainers about reported issues.");
|
||||||
|
logger.warn("");
|
||||||
|
logger.warn(
|
||||||
|
"For more or less details, use 'maven.plugin.validation' property with one of the values (case insensitive): {}",
|
||||||
|
Arrays.toString(ValidationLevel.values()));
|
||||||
|
logger.warn("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pluginDeclaration(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
InputLocation inputLocation =
|
||||||
|
mojoDescriptor.getPluginDescriptor().getPlugin().getLocation("");
|
||||||
|
if (inputLocation != null && inputLocation.getSource() != null) {
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
stringBuilder.append(inputLocation.getSource().getModelId());
|
||||||
|
String location = inputLocation.getSource().getLocation();
|
||||||
|
if (location != null) {
|
||||||
|
if (location.contains("://")) {
|
||||||
|
stringBuilder.append(" (").append(location).append(")");
|
||||||
|
} else {
|
||||||
|
File rootBasedir = mavenSession.getTopLevelProject().getBasedir();
|
||||||
|
File locationFile = new File(location);
|
||||||
|
if (location.startsWith(rootBasedir.getPath())) {
|
||||||
|
stringBuilder
|
||||||
|
.append(" (")
|
||||||
|
.append(rootBasedir.toPath().relativize(locationFile.toPath()))
|
||||||
|
.append(")");
|
||||||
|
} else {
|
||||||
|
stringBuilder.append(" (").append(location).append(")");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
stringBuilder.append(" @ line ").append(inputLocation.getLineNumber());
|
||||||
|
return stringBuilder.toString();
|
||||||
|
} else {
|
||||||
|
return "unknown";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String pluginOccurrence(MavenSession mavenSession) {
|
||||||
|
MavenProject prj = mavenSession.getCurrentProject();
|
||||||
|
String result = prj.getGroupId() + ":" + prj.getArtifactId() + ":" + prj.getVersion();
|
||||||
|
File currentPom = prj.getFile();
|
||||||
|
if (currentPom != null) {
|
||||||
|
File rootBasedir = mavenSession.getTopLevelProject().getBasedir();
|
||||||
|
result += " (" + rootBasedir.toPath().relativize(currentPom.toPath()) + ")";
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String mojoInfo(MojoDescriptor mojoDescriptor, Class<?> mojoClass) {
|
||||||
|
return mojoDescriptor.getFullGoalName() + " (" + mojoClass.getName() + ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private ConcurrentHashMap<String, PluginValidationIssues> pluginIssues(RepositorySystemSession session) {
|
||||||
|
return (ConcurrentHashMap<String, PluginValidationIssues>)
|
||||||
|
session.getData().computeIfAbsent(ISSUES_KEY, ConcurrentHashMap::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class PluginValidationIssues {
|
||||||
|
private final LinkedHashSet<String> pluginDeclarations;
|
||||||
|
|
||||||
|
private final LinkedHashSet<String> pluginOccurrences;
|
||||||
|
|
||||||
|
private final LinkedHashSet<String> pluginIssues;
|
||||||
|
|
||||||
|
private final LinkedHashMap<String, LinkedHashSet<String>> mojoIssues;
|
||||||
|
|
||||||
|
private PluginValidationIssues() {
|
||||||
|
this.pluginDeclarations = new LinkedHashSet<>();
|
||||||
|
this.pluginOccurrences = new LinkedHashSet<>();
|
||||||
|
this.pluginIssues = new LinkedHashSet<>();
|
||||||
|
this.mojoIssues = new LinkedHashMap<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void reportPluginIssue(String pluginDeclaration, String pluginOccurrence, String issue) {
|
||||||
|
if (pluginDeclaration != null) {
|
||||||
|
pluginDeclarations.add(pluginDeclaration);
|
||||||
|
}
|
||||||
|
if (pluginOccurrence != null) {
|
||||||
|
pluginOccurrences.add(pluginOccurrence);
|
||||||
|
}
|
||||||
|
pluginIssues.add(issue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void reportPluginMojoIssue(
|
||||||
|
String pluginDeclaration, String pluginOccurrence, String mojoInfo, String issue) {
|
||||||
|
if (pluginDeclaration != null) {
|
||||||
|
pluginDeclarations.add(pluginDeclaration);
|
||||||
|
}
|
||||||
|
if (pluginOccurrence != null) {
|
||||||
|
pluginOccurrences.add(pluginOccurrence);
|
||||||
|
}
|
||||||
|
mojoIssues.computeIfAbsent(mojoInfo, k -> new LinkedHashSet<>()).add(issue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,12 +18,15 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.maven.plugin.internal;
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.apache.maven.plugin.descriptor.Parameter;
|
import org.apache.maven.plugin.descriptor.Parameter;
|
||||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
||||||
|
@ -40,7 +43,7 @@ class DeprecatedCoreExpressionValidator extends AbstractMavenPluginParametersVal
|
||||||
private static final HashMap<String, String> DEPRECATED_CORE_PARAMETERS;
|
private static final HashMap<String, String> DEPRECATED_CORE_PARAMETERS;
|
||||||
|
|
||||||
private static final String ARTIFACT_REPOSITORY_REASON =
|
private static final String ARTIFACT_REPOSITORY_REASON =
|
||||||
"Avoid use of ArtifactRepository type. If you need access to local repository, switch to '${repositorySystemSession}' expression and get LRM from it instead.";
|
"ArtifactRepository type is deprecated and its use in Mojos should be avoided.";
|
||||||
|
|
||||||
static {
|
static {
|
||||||
HashMap<String, String> deprecatedCoreParameters = new HashMap<>();
|
HashMap<String, String> deprecatedCoreParameters = new HashMap<>();
|
||||||
|
@ -49,21 +52,33 @@ class DeprecatedCoreExpressionValidator extends AbstractMavenPluginParametersVal
|
||||||
DEPRECATED_CORE_PARAMETERS = deprecatedCoreParameters;
|
DEPRECATED_CORE_PARAMETERS = deprecatedCoreParameters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DeprecatedCoreExpressionValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getParameterLogReason(Parameter parameter) {
|
protected String getParameterLogReason(Parameter parameter) {
|
||||||
return "is deprecated core expression; " + DEPRECATED_CORE_PARAMETERS.get(parameter.getDefaultValue());
|
return "uses deprecated parameter expression '" + parameter.getDefaultValue() + "': "
|
||||||
|
+ DEPRECATED_CORE_PARAMETERS.get(parameter.getDefaultValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doValidate(
|
protected void doValidate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator) {
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
if (mojoDescriptor.getParameters() == null) {
|
if (mojoDescriptor.getParameters() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mojoDescriptor.getParameters().stream().filter(this::isDeprecated).forEach(this::logParameter);
|
mojoDescriptor.getParameters().stream()
|
||||||
|
.filter(this::isDeprecated)
|
||||||
|
.map(this::formatParameter)
|
||||||
|
.forEach(m -> pluginValidationManager.reportPluginMojoValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, m));
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isDeprecated(Parameter parameter) {
|
private boolean isDeprecated(Parameter parameter) {
|
||||||
|
|
|
@ -18,9 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.maven.plugin.internal;
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.apache.maven.plugin.descriptor.Parameter;
|
import org.apache.maven.plugin.descriptor.Parameter;
|
||||||
import org.apache.maven.shared.utils.logging.MessageUtils;
|
import org.apache.maven.shared.utils.logging.MessageUtils;
|
||||||
|
@ -35,6 +38,12 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
@Singleton
|
@Singleton
|
||||||
@Named
|
@Named
|
||||||
class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
|
class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
DeprecatedPluginValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getParameterLogReason(Parameter parameter) {
|
protected String getParameterLogReason(Parameter parameter) {
|
||||||
return "is deprecated: " + parameter.getDeprecated();
|
return "is deprecated: " + parameter.getDeprecated();
|
||||||
|
@ -42,36 +51,46 @@ class DeprecatedPluginValidator extends AbstractMavenPluginDescriptorSourcedPara
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doValidate(
|
protected void doValidate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator) {
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
if (mojoDescriptor.getDeprecated() != null) {
|
if (mojoDescriptor.getDeprecated() != null) {
|
||||||
logDeprecatedMojo(mojoDescriptor);
|
pluginValidationManager.reportPluginMojoValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, logDeprecatedMojo(mojoDescriptor));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mojoDescriptor.getParameters() != null) {
|
||||||
mojoDescriptor.getParameters().stream()
|
mojoDescriptor.getParameters().stream()
|
||||||
.filter(parameter -> parameter.getDeprecated() != null)
|
.filter(parameter -> parameter.getDeprecated() != null)
|
||||||
.filter(Parameter::isEditable)
|
.filter(Parameter::isEditable)
|
||||||
.forEach(parameter -> checkParameter(parameter, pomConfiguration, expressionEvaluator));
|
.forEach(parameter -> checkParameter(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, parameter, pomConfiguration, expressionEvaluator));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkParameter(
|
private void checkParameter(
|
||||||
Parameter parameter, PlexusConfiguration pomConfiguration, ExpressionEvaluator expressionEvaluator) {
|
MavenSession mavenSession,
|
||||||
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
|
Parameter parameter,
|
||||||
|
PlexusConfiguration pomConfiguration,
|
||||||
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
|
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
|
||||||
|
|
||||||
if (isValueSet(config, expressionEvaluator)) {
|
if (isValueSet(config, expressionEvaluator)) {
|
||||||
logParameter(parameter);
|
pluginValidationManager.reportPluginMojoValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, formatParameter(parameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void logDeprecatedMojo(MojoDescriptor mojoDescriptor) {
|
private String logDeprecatedMojo(MojoDescriptor mojoDescriptor) {
|
||||||
String message = MessageUtils.buffer()
|
return MessageUtils.buffer()
|
||||||
.warning("Goal '")
|
.warning("Goal '")
|
||||||
.warning(mojoDescriptor.getGoal())
|
.warning(mojoDescriptor.getGoal())
|
||||||
.warning("' is deprecated: ")
|
.warning("' is deprecated: ")
|
||||||
.warning(mojoDescriptor.getDeprecated())
|
.warning(mojoDescriptor.getDeprecated())
|
||||||
.toString();
|
.toString();
|
||||||
|
|
||||||
logger.warn(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
import org.codehaus.plexus.component.repository.ComponentDependency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects Maven2 plugins.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
@Named
|
||||||
|
class Maven2DependenciesValidator extends AbstractMavenPluginDependenciesValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
Maven2DependenciesValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
Set<String> maven2Versions = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
|
||||||
|
.filter(d -> "org.apache.maven".equals(d.getGroupId()))
|
||||||
|
.filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
|
||||||
|
.map(ComponentDependency::getVersion)
|
||||||
|
.filter(v -> v.startsWith("2."))
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (!maven2Versions.isEmpty()) {
|
||||||
|
pluginValidationManager.reportPluginValidationIssue(
|
||||||
|
mavenSession,
|
||||||
|
mojoDescriptor,
|
||||||
|
"Plugin is a Maven 2.x plugin, which will be not supported in Maven 4.x");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
import org.codehaus.plexus.component.repository.ComponentDependency;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects mixed Maven versions in plugins.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
@Named
|
||||||
|
class MavenMixedDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MavenMixedDependenciesValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
Set<String> mavenVersions = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
|
||||||
|
.filter(d -> "org.apache.maven".equals(d.getGroupId()))
|
||||||
|
.filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
|
||||||
|
.map(ComponentDependency::getVersion)
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (mavenVersions.size() > 1) {
|
||||||
|
pluginValidationManager.reportPluginValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, "Plugin mixes multiple Maven versions: " + mavenVersions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,6 +18,7 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.maven.plugin.internal;
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
||||||
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
|
@ -29,10 +30,12 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
*/
|
*/
|
||||||
interface MavenPluginConfigurationValidator {
|
interface MavenPluginConfigurationValidator {
|
||||||
/**
|
/**
|
||||||
* Check mojo configuration.
|
* Checks mojo configuration issues.
|
||||||
*/
|
*/
|
||||||
void validate(
|
void validate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator);
|
ExpressionEvaluator expressionEvaluator);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service responsible for validating plugin dependencies.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
interface MavenPluginDependenciesValidator {
|
||||||
|
/**
|
||||||
|
* Checks mojo dependency issues.
|
||||||
|
*/
|
||||||
|
void validate(MavenSession mavenSession, MojoDescriptor mojoDescriptor);
|
||||||
|
}
|
|
@ -0,0 +1,62 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects Maven3 artifacts in bad scope in plugins.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
@Named
|
||||||
|
class MavenScopeDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
MavenScopeDependenciesValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
Set<String> mavenArtifacts = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
|
||||||
|
.filter(d -> "org.apache.maven".equals(d.getGroupId()))
|
||||||
|
.filter(d -> !expectedProvidedScopeExclusions.contains(d.getGroupId() + ":" + d.getArtifactId()))
|
||||||
|
.filter(d -> d.getVersion().startsWith("3."))
|
||||||
|
.map(d -> d.getGroupId() + ":" + d.getArtifactId() + ":" + d.getVersion())
|
||||||
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
|
if (!mavenArtifacts.isEmpty()) {
|
||||||
|
pluginValidationManager.reportPluginValidationIssue(
|
||||||
|
mavenSession,
|
||||||
|
mojoDescriptor,
|
||||||
|
"Plugin should declare these Maven artifacts in `provided` scope: " + mavenArtifacts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,53 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.inject.Named;
|
||||||
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Detects Plexus Container Default in plugins.
|
||||||
|
*
|
||||||
|
* @since 3.9.2
|
||||||
|
*/
|
||||||
|
@Singleton
|
||||||
|
@Named
|
||||||
|
class PlexusContainerDefaultDependenciesValidator extends AbstractMavenPluginDependenciesValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
PlexusContainerDefaultDependenciesValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void doValidate(MavenSession mavenSession, MojoDescriptor mojoDescriptor) {
|
||||||
|
boolean pcdPresent = mojoDescriptor.getPluginDescriptor().getDependencies().stream()
|
||||||
|
.filter(d -> "org.codehaus.plexus".equals(d.getGroupId()))
|
||||||
|
.anyMatch(d -> "plexus-container-default".equals(d.getArtifactId()));
|
||||||
|
|
||||||
|
if (pcdPresent) {
|
||||||
|
pluginValidationManager.reportPluginValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, "Plugin depends on plexus-container-default, which is EOL");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,9 +18,12 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.maven.plugin.internal;
|
package org.apache.maven.plugin.internal;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
import javax.inject.Named;
|
import javax.inject.Named;
|
||||||
import javax.inject.Singleton;
|
import javax.inject.Singleton;
|
||||||
|
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.plugin.PluginValidationManager;
|
||||||
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
import org.apache.maven.plugin.descriptor.MojoDescriptor;
|
||||||
import org.apache.maven.plugin.descriptor.Parameter;
|
import org.apache.maven.plugin.descriptor.Parameter;
|
||||||
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
import org.codehaus.plexus.component.configurator.expression.ExpressionEvaluator;
|
||||||
|
@ -34,6 +37,12 @@ import org.codehaus.plexus.configuration.PlexusConfiguration;
|
||||||
@Named
|
@Named
|
||||||
@Singleton
|
@Singleton
|
||||||
class ReadOnlyPluginParametersValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
|
class ReadOnlyPluginParametersValidator extends AbstractMavenPluginDescriptorSourcedParametersValidator {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
ReadOnlyPluginParametersValidator(PluginValidationManager pluginValidationManager) {
|
||||||
|
super(pluginValidationManager);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected String getParameterLogReason(Parameter parameter) {
|
protected String getParameterLogReason(Parameter parameter) {
|
||||||
return "is read-only, must not be used in configuration";
|
return "is read-only, must not be used in configuration";
|
||||||
|
@ -41,7 +50,9 @@ class ReadOnlyPluginParametersValidator extends AbstractMavenPluginDescriptorSou
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void doValidate(
|
protected void doValidate(
|
||||||
|
MavenSession mavenSession,
|
||||||
MojoDescriptor mojoDescriptor,
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
PlexusConfiguration pomConfiguration,
|
PlexusConfiguration pomConfiguration,
|
||||||
ExpressionEvaluator expressionEvaluator) {
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
if (mojoDescriptor.getParameters() == null) {
|
if (mojoDescriptor.getParameters() == null) {
|
||||||
|
@ -50,15 +61,22 @@ class ReadOnlyPluginParametersValidator extends AbstractMavenPluginDescriptorSou
|
||||||
|
|
||||||
mojoDescriptor.getParameters().stream()
|
mojoDescriptor.getParameters().stream()
|
||||||
.filter(parameter -> !parameter.isEditable())
|
.filter(parameter -> !parameter.isEditable())
|
||||||
.forEach(parameter -> checkParameter(parameter, pomConfiguration, expressionEvaluator));
|
.forEach(parameter -> checkParameter(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, parameter, pomConfiguration, expressionEvaluator));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkParameter(
|
private void checkParameter(
|
||||||
Parameter parameter, PlexusConfiguration pomConfiguration, ExpressionEvaluator expressionEvaluator) {
|
MavenSession mavenSession,
|
||||||
|
MojoDescriptor mojoDescriptor,
|
||||||
|
Class<?> mojoClass,
|
||||||
|
Parameter parameter,
|
||||||
|
PlexusConfiguration pomConfiguration,
|
||||||
|
ExpressionEvaluator expressionEvaluator) {
|
||||||
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
|
PlexusConfiguration config = pomConfiguration.getChild(parameter.getName(), false);
|
||||||
|
|
||||||
if (isValueSet(config, expressionEvaluator)) {
|
if (isValueSet(config, expressionEvaluator)) {
|
||||||
logParameter(parameter);
|
pluginValidationManager.reportPluginMojoValidationIssue(
|
||||||
|
mavenSession, mojoDescriptor, mojoClass, formatParameter(parameter));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue