diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java index 95126446c1975..1b4462e41cff5 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java @@ -1,6 +1,7 @@ package io.quarkus.devtools.commands.handlers; import static io.quarkus.devtools.commands.AddExtensions.EXTENSION_MANAGER; +import static io.quarkus.platform.tools.ConsoleMessageFormats.nok; import io.quarkus.devtools.commands.AddExtensions; import io.quarkus.devtools.commands.data.QuarkusCommandException; @@ -12,6 +13,7 @@ import io.quarkus.platform.tools.ConsoleMessageFormats; import io.quarkus.registry.DefaultExtensionRegistry; import io.quarkus.registry.ExtensionRegistry; +import io.quarkus.registry.MultipleExtensionsFoundException; import java.io.IOException; import java.util.Collections; import java.util.Set; @@ -34,11 +36,11 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws extensionRegistry = DefaultExtensionRegistry.fromPlatform(invocation.getPlatformDescriptor()); } String quarkusVersion = invocation.getPlatformDescriptor().getQuarkusVersion(); - ExtensionInstallPlan extensionInstallPlan = extensionRegistry.planInstallation(quarkusVersion, extensionsQuery); final ExtensionManager extensionManager = invocation.getValue(EXTENSION_MANAGER, invocation.getQuarkusProject().getExtensionManager()); try { + ExtensionInstallPlan extensionInstallPlan = extensionRegistry.planInstallation(quarkusVersion, extensionsQuery); if (extensionInstallPlan.isNotEmpty()) { final InstallResult result = extensionManager.install(extensionInstallPlan); result.getInstalled() @@ -47,7 +49,15 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws + " has been installed")); return new QuarkusCommandOutcome(true).setValue(AddExtensions.OUTCOME_UPDATED, result.isSourceUpdated()); } - + } catch (MultipleExtensionsFoundException m) { + StringBuilder sb = new StringBuilder(); + sb.append(nok("Multiple extensions matching '")).append(m.getKeyword()).append("'"); + m.getExtensions() + .forEach(extension -> sb.append(System.lineSeparator()).append(" * ") + .append(extension.managementKey())); + sb.append(System.lineSeparator()) + .append(" Be more specific e.g using the exact name or the full GAV."); + invocation.log().info(sb.toString()); } catch (IOException e) { throw new QuarkusCommandException("Failed to add extensions", e); } diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/DefaultExtensionRegistry.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/DefaultExtensionRegistry.java index 1f2441e105b62..7b2aff278e8a7 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/DefaultExtensionRegistry.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/DefaultExtensionRegistry.java @@ -107,6 +107,12 @@ public ExtensionInstallPlan planInstallation(String quarkusCore, Collection 1 && !ExtensionPredicate.isPattern(keyword)) { + throw new MultipleExtensionsFoundException(keyword, + tuples.stream().map(this::toQuarkusExtension).collect(Collectors.toList())); + } for (ExtensionReleaseTuple tuple : tuples) { ArtifactKey id = tuple.getExtension().getId(); String groupId = id.getGroupId(); diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/MultipleExtensionsFoundException.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/MultipleExtensionsFoundException.java new file mode 100644 index 0000000000000..d036b8393b1de --- /dev/null +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/registry/MultipleExtensionsFoundException.java @@ -0,0 +1,30 @@ +package io.quarkus.registry; + +import io.quarkus.dependencies.Extension; +import java.util.Collection; +import java.util.Objects; + +/** + * Thrown when multiple extensions are found for a given extension when + * {@link ExtensionRegistry#planInstallation(String, Collection)} is called + * + * @see {@link ExtensionRegistry#planInstallation(String, Collection)} + */ +public class MultipleExtensionsFoundException extends RuntimeException { + + private final String keyword; + private final Collection extensions; + + public MultipleExtensionsFoundException(String keyword, Collection extensions) { + this.keyword = Objects.requireNonNull(keyword, "Keyword must not be null"); + this.extensions = Objects.requireNonNull(extensions, "Extensions should not be null"); + } + + public String getKeyword() { + return keyword; + } + + public Collection getExtensions() { + return extensions; + } +} diff --git a/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/dependencies/ExtensionPredicate.java b/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/dependencies/ExtensionPredicate.java index 2937990bf37e5..6655a1de710cc 100644 --- a/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/dependencies/ExtensionPredicate.java +++ b/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/dependencies/ExtensionPredicate.java @@ -21,6 +21,28 @@ public static Predicate create(String keyword) { return new ExtensionPredicate(keyword); } + public static boolean isPattern(String keyword) { + for (char c : keyword.toCharArray()) { + switch (c) { + case '*': + case '?': + case '^': // escape character in cmd.exe + case '(': + case ')': + case '[': + case ']': + case '$': + case '.': + case '{': + case '}': + case '|': + case '\\': + return true; + } + } + return false; + } + @Override public boolean test(Extension extension) { if (extension.isUnlisted()) {