Skip to content

Commit

Permalink
Merge pull request quarkusio#32173 from iocanel/cli-plug-fixes
Browse files Browse the repository at this point in the history
CLI plugin improvements
  • Loading branch information
gsmet authored Mar 30, 2023
2 parents 9cbf5bb + 613a080 commit 7451926
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 12 deletions.
31 changes: 25 additions & 6 deletions devtools/cli/src/main/java/io/quarkus/cli/QuarkusCli.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,16 @@
import io.quarkus.cli.common.HelpOption;
import io.quarkus.cli.common.OutputOptionMixin;
import io.quarkus.cli.common.PropertiesOptions;
import io.quarkus.cli.common.TargetQuarkusPlatformGroup;
import io.quarkus.cli.plugin.Plugin;
import io.quarkus.cli.plugin.PluginCommandFactory;
import io.quarkus.cli.plugin.PluginManager;
import io.quarkus.cli.plugin.PluginManagerSettings;
import io.quarkus.cli.registry.RegistryClientMixin;
import io.quarkus.cli.utils.Registries;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.devtools.project.QuarkusProjectHelper;
import io.quarkus.devtools.utils.Prompt;
import io.quarkus.runtime.QuarkusApplication;
import picocli.CommandLine;
Expand Down Expand Up @@ -79,8 +83,9 @@ public int run(String... args) throws Exception {

//When running tests the cli should not prompt for user input.
boolean interactiveMode = Arrays.stream(args).noneMatch(arg -> arg.equals("--cli-test"));
Optional<String> testDir = Arrays.stream(args).dropWhile(arg -> !arg.equals("--cli-test-dir")).skip(1).findFirst();
PluginCommandFactory pluginCommandFactory = new PluginCommandFactory(output);
PluginManager pluginManager = pluginManager(output, interactiveMode);
PluginManager pluginManager = pluginManager(output, testDir, interactiveMode);
pluginManager.syncIfNeeded();
Map<String, Plugin> plugins = new HashMap<>(pluginManager.getInstalledPlugins());
pluginCommandFactory.populateCommands(cmd, plugins);
Expand Down Expand Up @@ -220,20 +225,34 @@ private String description(UsageMessageSpec usageMessage) {
}
}

private static Optional<Path> getProjectRoot(OutputOptionMixin output) {
Path projectRoot = output != null ? output.getTestDirectory() : null;
private Optional<Path> getProjectRoot(Optional<String> testDir) {
Path projectRoot = testDir.map(Paths::get).orElse(null);

if (projectRoot == null) {
projectRoot = Paths.get(System.getProperty("user.dir")).toAbsolutePath();
}
return Optional.ofNullable(projectRoot);
}

private PluginManager pluginManager(OutputOptionMixin output, boolean interactiveMode) {
private Optional<QuarkusProject> quarkusProject(Optional<String> testDir) {
try {
Path root = getProjectRoot(testDir).orElseThrow();
BuildTool buildTool = QuarkusProjectHelper.detectExistingBuildTool(root);
if (buildTool == null) {
return Optional.empty();
}
return Optional
.ofNullable(registryClient.createQuarkusProject(root, new TargetQuarkusPlatformGroup(), buildTool, output));
} catch (Exception e) {
return Optional.empty();
}
}

private PluginManager pluginManager(OutputOptionMixin output, Optional<String> testDir, boolean interactiveMode) {
PluginManagerSettings settings = PluginManagerSettings.defaultSettings()
.withCatalogs(Registries.getRegistries(registryClient, "quarkusio"))
.withInteractivetMode(interactiveMode); // Why not just getting it from output.isClieTest ? Cause args have not been parsed yet.

return new PluginManager(settings, output, Optional.ofNullable(Paths.get(System.getProperty("user.home"))),
getProjectRoot(output), Optional.empty(), p -> true);
getProjectRoot(testDir), quarkusProject(testDir), p -> true);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
Expand All @@ -34,7 +36,17 @@ public static PluginCatalog combine(Optional<PluginCatalog> userCatalog, Optiona
Map<String, Plugin> plugins = new HashMap<>();
plugins.putAll(userCatalog.map(PluginCatalog::getPlugins).orElse(Collections.emptyMap()));
plugins.putAll(projectCatalog.map(PluginCatalog::getPlugins).orElse(Collections.emptyMap()));
return new PluginCatalog(plugins);

Optional<LocalDateTime> projectCatalogDate = projectCatalog.map(c -> c.getLastUpdateDate());
Optional<LocalDateTime> userCatalogDate = projectCatalog.map(c -> c.getLastUpdateDate());

LocalDateTime lastUpdated = Stream.of(projectCatalogDate, userCatalogDate)
.filter(Optional::isPresent)
.map(Optional::get)
.max(Comparator.naturalOrder())
.orElse(LocalDateTime.now());

return new PluginCatalog(VERSION, lastUpdated, plugins, Optional.empty());
}

public PluginCatalog() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ private boolean reconcile(PluginCatalog catalog) {
*/
public boolean sync() {
boolean catalogModified = reconcile();
Map<String, Plugin> installedPlugins = getInstallablePlugins();
Map<String, Plugin> installedPlugins = getInstalledPlugins();
Map<String, Plugin> extensionPlugins = state.getExtensionPlugins();
Map<String, Plugin> pluginsToInstall = extensionPlugins.entrySet().stream()
.filter(e -> !installedPlugins.containsKey(e.getKey()))
Expand All @@ -194,6 +194,11 @@ public boolean sync() {
addPlugin(plugin);
});
state.invalidate();
if (!catalogModified) {
PluginCatalogService pluginCatalogService = state.getPluginCatalogService();
PluginCatalog catalog = state.getPluginCatalog();
pluginCatalogService.writeCatalog(catalog);
}
return catalogModified;
}

Expand All @@ -206,11 +211,10 @@ public boolean syncIfNeeded() {
//syncing may require user interaction, so just return false
return false;
}

PluginCatalog catalog = state.getCombinedCatalog();
if (PluginUtil.shouldSync(state.getProjectRoot(), catalog)) {
output.info("Plugin catalog last updated on: " + catalog.getLastUpdate() + ". Syncing!");
return true;
return sync();
}
return false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ class PluginMangerState {
Optional<QuarkusProject> quarkusProject,
Predicate<Plugin> pluginFilter) {
this.settings = settings;
this.output = output;
this.userHome = userHome;
this.quarkusProject = quarkusProject;
this.pluginFilter = pluginFilter;
Expand All @@ -38,6 +39,7 @@ class PluginMangerState {
}

private final PluginManagerSettings settings;
private final MessageWriter output;
private final PluginManagerUtil util;
private final Optional<Path> userHome;
private final Optional<Path> projectRoot;
Expand Down Expand Up @@ -186,8 +188,8 @@ public Map<String, Plugin> extensionPlugins() {
.filter(e -> installed.contains(e.getArtifact().getKey()))
.map(ExtensionProcessor::getCliPlugins).flatMap(Collection::stream).map(util::from)
.collect(Collectors.toMap(p -> p.getName(), p -> p.inProjectCatalog())));
} catch (Exception e) {
throw new RuntimeException("Error reading the extension catalog", e);
} catch (Exception ignore) {
output.warn("Failed to read the extension catalog. Ignoring extension plugins.");
}
});
return extensionPlugins;
Expand Down

0 comments on commit 7451926

Please sign in to comment.