1
0
mirror of synced 2025-12-25 02:09:19 -05:00

add cli commons to factor out common parsing code (#7301)

This commit is contained in:
Charles
2021-10-29 18:44:22 -07:00
committed by GitHub
parent fdcbfd9fa7
commit 58902f3df8
7 changed files with 238 additions and 88 deletions

View File

@@ -4,6 +4,10 @@ plugins {
}
dependencies {
implementation project(':airbyte-protocol:models')
implementation project(':airbyte-commons-cli')
implementation project(':airbyte-json-validation')
implementation 'commons-cli:commons-cli:1.4'
implementation 'org.apache.sshd:sshd-mina:2.7.0'
// bouncycastle is pinned to version-match the transitive dependency from kubernetes client-java
@@ -12,8 +16,6 @@ dependencies {
implementation 'org.bouncycastle:bcpkix-jdk15on:1.66'
implementation 'org.bouncycastle:bctls-jdk15on:1.66'
implementation project(':airbyte-protocol:models')
implementation project(":airbyte-json-validation")
implementation "org.testcontainers:testcontainers:1.15.3"
implementation "org.testcontainers:jdbc:1.15.3"

View File

@@ -5,19 +5,14 @@
package io.airbyte.integrations.base;
import com.google.common.base.Preconditions;
import io.airbyte.commons.cli.Clis;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.DefaultParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -30,31 +25,28 @@ public class IntegrationCliParser {
private static final Logger LOGGER = LoggerFactory.getLogger(IntegrationCliParser.class);
private static final OptionGroup COMMAND_GROUP = new OptionGroup();
static {
COMMAND_GROUP.setRequired(true);
COMMAND_GROUP.addOption(Option.builder()
.longOpt(Command.SPEC.toString().toLowerCase())
.desc("outputs the json configuration specification")
.build());
COMMAND_GROUP.addOption(Option.builder()
.longOpt(Command.CHECK.toString().toLowerCase())
.desc("checks the config can be used to connect")
.build());
COMMAND_GROUP.addOption(Option.builder()
.longOpt(Command.DISCOVER.toString().toLowerCase())
.desc("outputs a catalog describing the source's catalog")
.build());
COMMAND_GROUP.addOption(Option.builder()
.longOpt(Command.READ.toString().toLowerCase())
.desc("reads the source and outputs messages to STDOUT")
.build());
COMMAND_GROUP.addOption(Option.builder()
.longOpt(Command.WRITE.toString().toLowerCase())
.desc("writes messages from STDIN to the integration")
.build());
}
private static final OptionGroup COMMAND_GROUP = Clis.createOptionGroup(
true,
Option.builder()
.longOpt(Command.SPEC.toString().toLowerCase())
.desc("outputs the json configuration specification")
.build(),
Option.builder()
.longOpt(Command.CHECK.toString().toLowerCase())
.desc("checks the config can be used to connect")
.build(),
Option.builder()
.longOpt(Command.DISCOVER.toString().toLowerCase())
.desc("outputs a catalog describing the source's catalog")
.build(),
Option.builder()
.longOpt(Command.READ.toString().toLowerCase())
.desc("reads the source and outputs messages to STDOUT")
.build(),
Option.builder()
.longOpt(Command.WRITE.toString().toLowerCase())
.desc("writes messages from STDIN to the integration")
.build());
public IntegrationConfig parse(final String[] args) {
final Command command = parseCommand(args);
@@ -62,20 +54,11 @@ public class IntegrationCliParser {
}
private static Command parseCommand(final String[] args) {
final CommandLineParser parser = new RelaxedParser();
final HelpFormatter helpFormatter = new HelpFormatter();
final Options options = new Options();
options.addOptionGroup(COMMAND_GROUP);
try {
final CommandLine parsed = parser.parse(options, args);
return Command.valueOf(parsed.getOptions()[0].getLongOpt().toUpperCase());
// if discover, then validate, etc...
} catch (final ParseException e) {
helpFormatter.printHelp("java-base", options);
throw new IllegalArgumentException(e);
}
final CommandLine parsed = Clis.parse(args, options, Clis.getRelaxedParser());
return Command.valueOf(parsed.getOptions()[0].getLongOpt().toUpperCase());
}
private static IntegrationConfig parseOptions(final String[] args, final Command command) {
@@ -87,26 +70,46 @@ public class IntegrationCliParser {
case SPEC -> {
// no args.
}
case CHECK, DISCOVER -> options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_CONFIG_KEY).desc(JavaBaseConstants.ARGS_CONFIG_DESC).hasArg(true).required(true).build());
case CHECK, DISCOVER -> options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_CONFIG_KEY)
.desc(JavaBaseConstants.ARGS_CONFIG_DESC)
.hasArg(true)
.required(true)
.build());
case READ -> {
options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_CONFIG_KEY).desc(JavaBaseConstants.ARGS_CONFIG_DESC).hasArg(true).required(true).build());
options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_CATALOG_KEY).desc(JavaBaseConstants.ARGS_CATALOG_DESC).hasArg(true).build());
options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_STATE_KEY).desc(JavaBaseConstants.ARGS_PATH_DESC).hasArg(true).build());
options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_CONFIG_KEY)
.desc(JavaBaseConstants.ARGS_CONFIG_DESC)
.hasArg(true)
.required(true)
.build());
options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_CATALOG_KEY)
.desc(JavaBaseConstants.ARGS_CATALOG_DESC)
.hasArg(true)
.build());
options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_STATE_KEY)
.desc(JavaBaseConstants.ARGS_PATH_DESC)
.hasArg(true)
.build());
}
case WRITE -> {
options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_CONFIG_KEY).desc(JavaBaseConstants.ARGS_CONFIG_DESC).hasArg(true).required(true).build());
options.addOption(Option
.builder().longOpt(JavaBaseConstants.ARGS_CATALOG_KEY).desc(JavaBaseConstants.ARGS_CATALOG_DESC).hasArg(true).build());
options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_CONFIG_KEY)
.desc(JavaBaseConstants.ARGS_CONFIG_DESC)
.hasArg(true)
.required(true).build());
options.addOption(Option.builder()
.longOpt(JavaBaseConstants.ARGS_CATALOG_KEY)
.desc(JavaBaseConstants.ARGS_CATALOG_DESC)
.hasArg(true)
.build());
}
default -> throw new IllegalStateException("Unexpected value: " + command);
}
final CommandLine parsed = runParse(options, args, command);
final CommandLine parsed = Clis.parse(args, options, command.toString().toLowerCase());
Preconditions.checkNotNull(parsed);
final Map<String, String> argsMap = new HashMap<>();
for (final Option option : parsed.getOptions()) {
@@ -139,35 +142,4 @@ public class IntegrationCliParser {
}
}
private static CommandLine runParse(final Options options, final String[] args, final Command command) {
final CommandLineParser parser = new DefaultParser();
final HelpFormatter helpFormatter = new HelpFormatter();
try {
return parser.parse(options, args);
} catch (final ParseException e) {
helpFormatter.printHelp(command.toString().toLowerCase(), options);
throw new IllegalArgumentException(e);
}
}
// https://stackoverflow.com/questions/33874902/apache-commons-cli-1-3-1-how-to-ignore-unknown-arguments
private static class RelaxedParser extends DefaultParser {
@Override
public CommandLine parse(final Options options, final String[] arguments) throws ParseException {
final List<String> knownArgs = new ArrayList<>();
for (int i = 0; i < arguments.length; i++) {
if (options.hasOption(arguments[i])) {
knownArgs.add(arguments[i]);
if (i + 1 < arguments.length && options.getOption(arguments[i]).hasArg()) {
knownArgs.add(arguments[i + 1]);
}
}
}
return super.parse(options, knownArgs.toArray(new String[0]));
}
}
}