Skip to content

Commit

Permalink
Merge pull request #946 from jpmorganchase/use-picocli-for-main-cli
Browse files Browse the repository at this point in the history
Use picocli for main cli
  • Loading branch information
Krish1979 authored Dec 30, 2019
2 parents d445165 + 8bd8b94 commit 54dcf99
Show file tree
Hide file tree
Showing 69 changed files with 2,656 additions and 2,863 deletions.
12 changes: 0 additions & 12 deletions cli/admin-cli/build.gradle

This file was deleted.

34 changes: 0 additions & 34 deletions cli/admin-cli/pom.xml

This file was deleted.

This file was deleted.

This file was deleted.

77 changes: 0 additions & 77 deletions cli/admin-cli/src/test/resources/sample-config.json

This file was deleted.

3 changes: 1 addition & 2 deletions cli/cli-api/build.gradle
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

dependencies {
compile 'info.picocli:picocli:4.0.4'
compile 'info.picocli:picocli'
compile 'org.apache.commons:commons-lang3:3.7'
compile 'commons-cli:commons-cli:1.4'
compile project(':config')
compile project(':shared')
compile project(':encryption:encryption-api')
Expand Down
1 change: 0 additions & 1 deletion cli/cli-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>4.0.4</version>
</dependency>

</dependencies>
Expand Down
85 changes: 3 additions & 82 deletions cli/cli-api/src/main/java/com/quorum/tessera/cli/CliDelegate.java
Original file line number Diff line number Diff line change
@@ -1,29 +1,13 @@
package com.quorum.tessera.cli;

import com.quorum.tessera.ServiceLoaderUtil;
import com.quorum.tessera.cli.parsers.ConfigConverter;
import com.quorum.tessera.config.Config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import picocli.CommandLine;

import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static picocli.CommandLine.Model.CommandSpec.DEFAULT_COMMAND_NAME;

// TODO(cjh) still using CliDelegate as a config store so that config can be injected by spring
public enum CliDelegate {
INSTANCE;

private static final Logger LOGGER = LoggerFactory.getLogger(CliDelegate.class);

private static final CliResult HELP_RESULT = new CliResult(0, true, null);

private static final CliResult DEFAULT_RESULT = new CliResult(1, true, null);

private Config config;

public static CliDelegate instance() {
Expand All @@ -36,70 +20,7 @@ public Config getConfig() {
() -> new IllegalStateException("Execute must be invoked before attempting to fetch config"));
}

public CliResult execute(String... args) throws Exception {

final List<CliAdapter> adapters = ServiceLoaderUtil.loadAll(CliAdapter.class).collect(Collectors.toList());

LOGGER.debug("Loaded adapters {}", adapters);

CliType cliType = CliType.valueOf(System.getProperty(CliType.CLI_TYPE_KEY, CliType.CONFIG.name()));

LOGGER.debug("cliType {}", cliType);

Predicate<CliAdapter> isTopLevel =
a -> a.getClass().getAnnotation(CommandLine.Command.class).name().equals(DEFAULT_COMMAND_NAME);

// Finds the top level adapter that we want to start with. Exactly one is expected to be on the classpath.
final CliAdapter adapter =
adapters.stream()
.filter(a -> a.getClass().isAnnotationPresent(CommandLine.Command.class))
.filter(isTopLevel)
.filter(a -> a.getType() == cliType)
.findFirst()
.get();

LOGGER.debug("Loaded adapter {}", adapter);

// Then we find all the others and attach them as sub-commands. It is expected that they have defined their
// own hierarchy and command names.
final List<CliAdapter> subcommands =
adapters.stream()
// .filter(isTopLevel)
.filter(a -> a != adapter)
.filter(a -> a.getType() != CliType.ENCLAVE)
.collect(Collectors.toList());

// the mapper will give us access to the exception from the outside, if one occurred.
// mostly since we have an existing system, and this is a workaround
final CLIExceptionCapturer mapper = new CLIExceptionCapturer();
final CommandLine commandLine = new CommandLine(adapter);

subcommands.stream().peek(sc -> LOGGER.debug("Adding subcommand {}", sc)).forEach(commandLine::addSubcommand);

commandLine
.registerConverter(Config.class, new ConfigConverter())
.setSeparator(" ")
.setCaseInsensitiveEnumValuesAllowed(true)
.setUnmatchedArgumentsAllowed(true)
.setExecutionExceptionHandler(mapper)
.setParameterExceptionHandler(mapper);

commandLine.execute(args);

// if an exception occurred, throw it to to the upper levels where it gets handled
if (mapper.getThrown() != null) {
throw mapper.getThrown();
}

// otherwise, set the config object (if there is one) and return
final CliResult result =
commandLine.getParseResult().asCommandLineList().stream()
.map(cl -> cl.isUsageHelpRequested() ? HELP_RESULT : cl.getExecutionResult())
.filter(Objects::nonNull)
.findFirst()
.orElse(DEFAULT_RESULT);

this.config = result.getConfig().orElse(null);
return result;
public void setConfig(Config config) {
this.config = config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.quorum.tessera.config.Config;
import com.quorum.tessera.config.ConfigFactory;
import com.quorum.tessera.config.util.ConfigFileStore;
import picocli.CommandLine;

import java.io.FileNotFoundException;
Expand All @@ -22,6 +23,8 @@ public Config convert(final String value) throws Exception {
throw new FileNotFoundException(String.format("%s not found.", path));
}

ConfigFileStore.create(path);

try (InputStream in = Files.newInputStream(path)) {
return configFactory.create(in);
}
Expand Down
Loading

0 comments on commit 54dcf99

Please sign in to comment.