From 9e5e684d59c9ed6630a32b3e53200a034687a034 Mon Sep 17 00:00:00 2001 From: Ioannis Canellos Date: Thu, 11 May 2023 18:58:34 +0300 Subject: [PATCH] fix: cli uses locally enabled jbang catalogs --- .../main/java/io/quarkus/cli/QuarkusCli.java | 2 - .../cli/plugin/JBangCatalogService.java | 48 ++++++++++++++++--- .../cli/plugin/PluginManagerSettings.java | 33 +++++++++---- .../quarkus/cli/plugin/PluginMangerState.java | 1 + 4 files changed, 68 insertions(+), 16 deletions(-) diff --git a/devtools/cli/src/main/java/io/quarkus/cli/QuarkusCli.java b/devtools/cli/src/main/java/io/quarkus/cli/QuarkusCli.java index 6e9481e7ffa45..4717a091f7a3c 100644 --- a/devtools/cli/src/main/java/io/quarkus/cli/QuarkusCli.java +++ b/devtools/cli/src/main/java/io/quarkus/cli/QuarkusCli.java @@ -10,7 +10,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.Set; import java.util.concurrent.Callable; import java.util.function.Supplier; @@ -264,7 +263,6 @@ private Supplier quarkusProject(Optional testDir) { private PluginManager pluginManager(OutputOptionMixin output, Optional testDir, boolean interactiveMode) { PluginManagerSettings settings = PluginManagerSettings.defaultSettings() - .withCatalogs(Set. of("quarkusio")) .withInteractivetMode(interactiveMode); // Why not just getting it from output.isClieTest ? Cause args have not been parsed yet. return PluginManager.create(settings, output, Optional.ofNullable(Paths.get(System.getProperty("user.home"))), getProjectRoot(testDir), quarkusProject(testDir)); diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/JBangCatalogService.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/JBangCatalogService.java index adf9abac11477..1a0825ed4b2e7 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/JBangCatalogService.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/JBangCatalogService.java @@ -19,6 +19,7 @@ public class JBangCatalogService extends CatalogService { private static final Pattern PATH = Pattern.compile(PATH_REGEX); private final String pluginPrefix; + private final String fallbackCatalog; private final String[] remoteCatalogs; private final JBangSupport jbang; @@ -26,13 +27,15 @@ public JBangCatalogService(MessageWriter output) { this(output, "quarkus", "quarkusio"); } - public JBangCatalogService(MessageWriter output, String pluginPrefix, String... remoteCatalogs) { - this(false, output, pluginPrefix, remoteCatalogs); + public JBangCatalogService(MessageWriter output, String pluginPrefix, String fallbackCatalog, String... remoteCatalogs) { + this(false, output, pluginPrefix, fallbackCatalog, remoteCatalogs); } - public JBangCatalogService(boolean interactiveMode, MessageWriter output, String pluginPrefix, String... remoteCatalogs) { + public JBangCatalogService(boolean interactiveMode, MessageWriter output, String pluginPrefix, String fallbackCatalog, + String... remoteCatalogs) { super(JBangCatalog.class, GIT_ROOT, RELATIVE_PLUGIN_CATALOG); this.pluginPrefix = pluginPrefix; + this.fallbackCatalog = fallbackCatalog; this.remoteCatalogs = remoteCatalogs; this.jbang = new JBangSupport(interactiveMode, output); } @@ -90,16 +93,49 @@ public JBangCatalog readCombinedCatalog(Optional projectDir, Optional lines = jbang.execute("alias", "list", "--verbose", remoteCatalog); - aliases.putAll(readAliases(lines).entrySet() + //If not catalog have been specified use all available. + if (remoteCatalogs.length == 0) { + aliases.putAll(listAliasesOrFallback(jbang, fallbackCatalog).entrySet() .stream() .filter(e -> !aliases.containsKey(e.getKey())) .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + } else { + for (String remoteCatalog : remoteCatalogs) { + aliases.putAll(listAliases(jbang, remoteCatalog).entrySet() + .stream() + .filter(e -> !aliases.containsKey(e.getKey())) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue))); + } } return new JBangCatalog(catalogs, aliases, Optional.empty(), Optional.empty()); } + private Map listAliases(JBangSupport jbang, String remoteCatalog) { + List lines = jbang.execute("alias", "list", "--verbose", remoteCatalog); + return readAliases(lines); + } + + private Map listAliasesOrFallback(JBangSupport jbang, String fallbackCatalog) { + List localCatalogs = jbang.execute("catalog", "list").stream() + .map(l -> l.substring(0, l.indexOf(" "))) + .collect(Collectors.toList()); + + //If there are locally installed catalogs, then go through every single one of them + //and collect the aliases. + //Unfortunaltely jbang can't return all alias in one go. + //This is because it currently omits `@catalog` suffix in some cases. + if (!localCatalogs.isEmpty()) { + Map aliases = new HashMap<>(); + for (String catalog : localCatalogs) { + aliases.putAll(listAliases(jbang, catalog)); + } + return aliases; + } + //If no aliases found then there is not remote jbang catalog available + //In this case we need to fallback to the default. + return listAliases(jbang, fallbackCatalog); + } + private Map readAliases(List lines) { Map aliases = new HashMap<>(); for (int i = 0; i < lines.size(); i++) { diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginManagerSettings.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginManagerSettings.java index 3619abbb5682b..03ea253caa7aa 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginManagerSettings.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginManagerSettings.java @@ -13,43 +13,51 @@ public class PluginManagerSettings { public static String DEFAULT_PLUGIN_PREFIX = "quarkus"; - public static String[] DEFAULT_REMOTE_JBANG_CATALOGS = new String[] { "quarkusio" }; + public static String FALLBACK_REMOTE_JBANG_CATALOG = "quarkusio"; + public static String[] DEFAULT_REMOTE_JBANG_CATALOGS = new String[0]; public static Function DEFAULT_RELATIVE_PATH_FUNC = p -> p.resolve(".quarkus").resolve("cli").resolve("plugins") .resolve("quarkus-cli-catalog.json"); private final boolean interactiveMode; private final String pluginPrefix; + private final String fallbackJBangCatalog; private final String[] remoteJBangCatalogs; private final Function toRelativePath; - public PluginManagerSettings(boolean interactiveMode, String pluginPrefix, String[] remoteJBangCatalogs, + public PluginManagerSettings(boolean interactiveMode, String pluginPrefix, String fallbackJBangCatalog, + String[] remoteJBangCatalogs, Function toRelativePath) { this.interactiveMode = interactiveMode; this.pluginPrefix = pluginPrefix; + this.fallbackJBangCatalog = fallbackJBangCatalog; this.remoteJBangCatalogs = remoteJBangCatalogs; this.toRelativePath = toRelativePath; } public static PluginManagerSettings defaultSettings() { - return new PluginManagerSettings(false, DEFAULT_PLUGIN_PREFIX, DEFAULT_REMOTE_JBANG_CATALOGS, + return new PluginManagerSettings(false, DEFAULT_PLUGIN_PREFIX, FALLBACK_REMOTE_JBANG_CATALOG, + DEFAULT_REMOTE_JBANG_CATALOGS, DEFAULT_RELATIVE_PATH_FUNC); } public PluginManagerSettings withPluignPrefix(String pluginPrefix) { - return new PluginManagerSettings(interactiveMode, pluginPrefix, remoteJBangCatalogs, toRelativePath); + return new PluginManagerSettings(interactiveMode, pluginPrefix, fallbackJBangCatalog, remoteJBangCatalogs, + toRelativePath); } public PluginManagerSettings withCatalogs(Set remoteJBangCatalogs) { - return new PluginManagerSettings(interactiveMode, pluginPrefix, - remoteJBangCatalogs.toArray(new String[remoteJBangCatalogs.size()]), toRelativePath); + return new PluginManagerSettings(interactiveMode, pluginPrefix, fallbackJBangCatalog, + remoteJBangCatalogs.toArray(new String[0]), toRelativePath); } public PluginManagerSettings withCatalogs(String... remoteJBangCatalogs) { - return new PluginManagerSettings(interactiveMode, pluginPrefix, remoteJBangCatalogs, toRelativePath); + return new PluginManagerSettings(interactiveMode, pluginPrefix, fallbackJBangCatalog, remoteJBangCatalogs, + toRelativePath); } public PluginManagerSettings withInteractivetMode(boolean interactiveMode) { - return new PluginManagerSettings(interactiveMode, pluginPrefix, remoteJBangCatalogs, toRelativePath); + return new PluginManagerSettings(interactiveMode, pluginPrefix, fallbackJBangCatalog, remoteJBangCatalogs, + toRelativePath); } /** @@ -63,6 +71,15 @@ public String getPluginPrefix() { return pluginPrefix; } + /** + * The name of the fallback JBang catalogs to get plugins from. + * + * @return the name of the catalog. + */ + public String getFallbackJBangCatalog() { + return fallbackJBangCatalog; + } + /** * The names of the JBang catalogs to get plugins from. * diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginMangerState.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginMangerState.java index 58ca824b8b172..4979d89d66664 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginMangerState.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/cli/plugin/PluginMangerState.java @@ -29,6 +29,7 @@ class PluginMangerState { //Inferred this.projectRoot = projectRoot.filter(p -> !p.equals(userHome.orElse(null))); this.jbangCatalogService = new JBangCatalogService(settings.isInteractiveMode(), output, settings.getPluginPrefix(), + settings.getFallbackJBangCatalog(), settings.getRemoteJBangCatalogs()); this.pluginCatalogService = new PluginCatalogService(settings.getToRelativePath()); this.util = PluginManagerUtil.getUtil(settings);