diff --git a/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java b/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java index 3c2cff77c32e..9e469f5f9ba7 100644 --- a/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java +++ b/impl/maven-core/src/main/java/org/apache/maven/plugin/prefix/internal/DefaultPluginPrefixResolver.java @@ -26,14 +26,21 @@ import java.nio.file.Files; import java.util.ArrayList; import java.util.Collections; -import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; +import java.util.stream.Stream; import org.apache.maven.artifact.repository.metadata.Metadata; import org.apache.maven.artifact.repository.metadata.io.MetadataReader; +import org.apache.maven.model.Build; +import org.apache.maven.model.Model; +import org.apache.maven.model.Plugin; +import org.apache.maven.model.PluginManagement; +import org.apache.maven.plugin.BuildPluginManager; +import org.apache.maven.plugin.descriptor.PluginDescriptor; import org.apache.maven.plugin.prefix.NoPluginFoundForPrefixException; import org.apache.maven.plugin.prefix.PluginPrefixRequest; import org.apache.maven.plugin.prefix.PluginPrefixResolver; @@ -65,11 +72,14 @@ public class DefaultPluginPrefixResolver implements PluginPrefixResolver { private static final String REPOSITORY_CONTEXT = org.apache.maven.api.services.RequestTrace.CONTEXT_PLUGIN; private final Logger logger = LoggerFactory.getLogger(getClass()); + private final BuildPluginManager pluginManager; private final RepositorySystem repositorySystem; private final MetadataReader metadataReader; @Inject - public DefaultPluginPrefixResolver(RepositorySystem repositorySystem, MetadataReader metadataReader) { + public DefaultPluginPrefixResolver( + BuildPluginManager pluginManager, RepositorySystem repositorySystem, MetadataReader metadataReader) { + this.pluginManager = pluginManager; this.repositorySystem = repositorySystem; this.metadataReader = metadataReader; } @@ -78,6 +88,10 @@ public DefaultPluginPrefixResolver(RepositorySystem repositorySystem, MetadataRe public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFoundForPrefixException { logger.debug("Resolving plugin prefix {} from {}", request.getPrefix(), request.getPluginGroups()); + Model pom = request.getPom(); + Build build = pom != null ? pom.getBuild() : null; + PluginManagement management = build != null ? build.getPluginManagement() : null; + // map of groupId -> Set(artifactId) plugin candidates: // if value is null, keys are coming from settings, and no artifactId filtering is applied // if value is non-null: we allow only plugins that have enlisted artifactId only @@ -85,26 +99,26 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo // end game is: settings enlisted groupIds are obeying order and are "free for all" (artifactId) // while POM enlisted plugins coming from non-enlisted settings groupIds (ie conflict of prefixes) // will prevail/win. - LinkedHashMap> candidates = new LinkedHashMap<>(); - if (request.getPom() != null) { - if (request.getPom().getBuild() != null) { - request.getPom().getBuild().getPlugins().stream() - .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) - .forEach(p -> candidates - .computeIfAbsent(p.getGroupId(), g -> new HashSet<>()) - .add(p.getArtifactId())); - if (request.getPom().getBuild().getPluginManagement() != null) { - request.getPom().getBuild().getPluginManagement().getPlugins().stream() - .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) - .forEach(p -> candidates - .computeIfAbsent(p.getGroupId(), g -> new HashSet<>()) - .add(p.getArtifactId())); - } - } - } + LinkedHashMap> candidates = Stream.of(build, management) + .flatMap(container -> container != null ? container.getPlugins().stream() : Stream.empty()) + .filter(p -> !request.getPluginGroups().contains(p.getGroupId())) + .collect(Collectors.groupingBy( + Plugin::getGroupId, + LinkedHashMap::new, + Collectors.mapping(Plugin::getArtifactId, Collectors.toSet()))); request.getPluginGroups().forEach(g -> candidates.put(g, null)); PluginPrefixResult result = resolveFromRepository(request, candidates); + // If we haven't been able to resolve the plugin from the repository, + // as a last resort, we go through all declared plugins, load them + // one by one, and try to find a matching prefix. + if (result == null && build != null) { + result = resolveFromProject(request, build.getPlugins()); + if (result == null && management != null) { + result = resolveFromProject(request, management.getPlugins()); + } + } + if (result == null) { throw new NoPluginFoundForPrefixException( request.getPrefix(), @@ -123,6 +137,27 @@ public PluginPrefixResult resolve(PluginPrefixRequest request) throws NoPluginFo return result; } + private PluginPrefixResult resolveFromProject(PluginPrefixRequest request, List plugins) { + for (Plugin plugin : plugins) { + try { + PluginDescriptor pluginDescriptor = + pluginManager.loadPlugin(plugin, request.getRepositories(), request.getRepositorySession()); + + if (request.getPrefix().equals(pluginDescriptor.getGoalPrefix())) { + return new DefaultPluginPrefixResult(plugin); + } + } catch (Exception e) { + if (logger.isDebugEnabled()) { + logger.warn("Failed to retrieve plugin descriptor for {}: {}", plugin.getId(), e.getMessage(), e); + } else { + logger.warn("Failed to retrieve plugin descriptor for {}: {}", plugin.getId(), e.getMessage()); + } + } + } + + return null; + } + private PluginPrefixResult resolveFromRepository( PluginPrefixRequest request, LinkedHashMap> candidates) { RequestTrace trace = RequestTrace.newChild(null, request);