Search in sources :

Example 51 with CommandLine

use of picocli.CommandLine in project liquibase by liquibase.

the class LiquibaseCommandLine method getParentCommandSpec.

private CommandLine.Model.CommandSpec getParentCommandSpec(CommandDefinition commandDefinition, CommandLine rootCommand) {
    final String[] commandName = commandDefinition.getName();
    CommandLine.Model.CommandSpec parent = rootCommand.getCommandSpec();
    // length-1 to not include the actual command name
    for (int i = 0; i < commandName.length - 1; i++) {
        final CommandLine commandGroup = parent.subcommands().get(commandName[i]);
        final String[] groupName = Arrays.copyOfRange(commandName, 0, i + 1);
        if (commandGroup == null) {
            parent = addSubcommandGroup(groupName, commandDefinition, parent);
        } else {
            parent = commandGroup.getCommandSpec();
            if (commandDefinition.getGroupHelpFooter() != null) {
                List<String> list = new ArrayList<>();
                list.add(commandDefinition.getHelpFooter());
                parent.usageMessage().footer(list.toArray(new String[0]));
            }
        }
        configureSubcommandGroup(parent, groupName, commandDefinition);
    }
    return parent;
}
Also used : CommandLine(picocli.CommandLine)

Example 52 with CommandLine

use of picocli.CommandLine in project liquibase by liquibase.

the class LiquibaseCommandLine method execute.

public int execute(String[] args) {
    try {
        final String[] finalArgs = adjustLegacyArgs(args);
        configureLogging(Level.OFF, null);
        Main.runningFromNewCli = true;
        final List<ConfigurationValueProvider> valueProviders = registerValueProviders(finalArgs);
        try {
            return Scope.child(configureScope(), () -> {
                if (!LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentValue()) {
                    Scope.getCurrentScope().getUI().sendErrorMessage((String.format(coreBundle.getString("did.not.run.because.param.was.set.to.false"), LiquibaseCommandLineConfiguration.SHOULD_RUN.getCurrentConfiguredValue().getProvidedValue().getActualKey())));
                    return 0;
                }
                configureVersionInfo();
                if (!wasHelpOrVersionRequested()) {
                    Scope.getCurrentScope().getUI().sendMessage(CommandLineUtils.getBanner());
                    Scope.getCurrentScope().getUI().sendMessage(String.format(coreBundle.getString("version.number"), LiquibaseUtil.getBuildVersionInfo()));
                    final LicenseService licenseService = Scope.getCurrentScope().getSingleton(LicenseServiceFactory.class).getLicenseService();
                    if (licenseService == null) {
                        Scope.getCurrentScope().getUI().sendMessage("WARNING: License service not loaded, cannot determine Liquibase Pro license status. Please consider re-installing Liquibase to include all dependencies. Continuing operation without Pro license.");
                    } else {
                        Scope.getCurrentScope().getUI().sendMessage(licenseService.getLicenseInfo());
                    }
                }
                CommandLine.ParseResult subcommandParseResult = commandLine.getParseResult();
                while (subcommandParseResult.hasSubcommand()) {
                    subcommandParseResult = subcommandParseResult.subcommand();
                }
                Map<String, String> changelogParameters = subcommandParseResult.matchedOptionValue("-D", new HashMap<>());
                if (changelogParameters.size() != 0) {
                    Main.newCliChangelogParameters = changelogParameters;
                }
                int response = commandLine.execute(finalArgs);
                if (!wasHelpOrVersionRequested()) {
                    final ConfiguredValue<File> logFile = LiquibaseCommandLineConfiguration.LOG_FILE.getCurrentConfiguredValue();
                    if (logFile.found()) {
                        Scope.getCurrentScope().getUI().sendMessage("Logs saved to " + logFile.getValue().getAbsolutePath());
                    }
                    final ConfiguredValue<File> outputFile = LiquibaseCommandLineConfiguration.OUTPUT_FILE.getCurrentConfiguredValue();
                    if (outputFile.found()) {
                        Scope.getCurrentScope().getUI().sendMessage("Output saved to " + outputFile.getValue().getAbsolutePath());
                    }
                    if (response == 0) {
                        final List<CommandLine> commandList = commandLine.getParseResult().asCommandLineList();
                        final String commandName = StringUtil.join(getCommandNames(commandList.get(commandList.size() - 1)), " ");
                        Scope.getCurrentScope().getUI().sendMessage("Liquibase command '" + commandName + "' was executed successfully.");
                    }
                }
                return response;
            });
        } finally {
            final LiquibaseConfiguration liquibaseConfiguration = Scope.getCurrentScope().getSingleton(LiquibaseConfiguration.class);
            for (ConfigurationValueProvider provider : valueProviders) {
                liquibaseConfiguration.unregisterProvider(provider);
            }
        }
    } catch (Throwable e) {
        handleException(e);
        return 1;
    } finally {
        cleanup();
    }
}
Also used : ConfigurationValueProvider(liquibase.configuration.ConfigurationValueProvider) CommandLine(picocli.CommandLine) LicenseService(liquibase.license.LicenseService) LicenseServiceFactory(liquibase.license.LicenseServiceFactory) LiquibaseConfiguration(liquibase.configuration.LiquibaseConfiguration)

Example 53 with CommandLine

use of picocli.CommandLine in project liquibase by liquibase.

the class LiquibaseCommandLine method addSubcommand.

private void addSubcommand(CommandDefinition commandDefinition, CommandLine rootCommand) {
    List<String[]> commandNames = expandCommandNames(commandDefinition);
    boolean showCommand = true;
    for (String[] commandName : commandNames) {
        final CommandRunner commandRunner = new CommandRunner();
        final CommandLine.Model.CommandSpec subCommandSpec = CommandLine.Model.CommandSpec.wrapWithoutInspection(commandRunner, defaultFactory);
        commandRunner.setSpec(subCommandSpec);
        configureHelp(subCommandSpec, false);
        // 
        if (commandDefinition.getHelpFooter() != null) {
            String[] usageMessageFooter = subCommandSpec.usageMessage().footer();
            List<String> list = new ArrayList<>(Arrays.asList(usageMessageFooter));
            list.add(commandDefinition.getHelpFooter());
            subCommandSpec.usageMessage().footer(list.toArray(new String[0]));
        }
        String shortDescription = commandDefinition.getShortDescription();
        String displayDescription = shortDescription;
        String legacyCommand = commandName[commandName.length - 1];
        String camelCaseCommand = StringUtil.toCamelCase(legacyCommand);
        if (!legacyCommand.equals(camelCaseCommand)) {
            displayDescription = "\n" + shortDescription + "\n[deprecated: " + camelCaseCommand + "]";
        }
        subCommandSpec.usageMessage().header(StringUtil.trimToEmpty(displayDescription) + "\n").description(StringUtil.trimToEmpty(commandDefinition.getLongDescription()));
        subCommandSpec.optionsCaseInsensitive(true);
        subCommandSpec.subcommandsCaseInsensitive(true);
        if (!showCommand) {
            subCommandSpec.usageMessage().hidden(true);
        } else {
            subCommandSpec.usageMessage().hidden(commandDefinition.getHidden());
        }
        showCommand = false;
        for (CommandArgumentDefinition<?> def : commandDefinition.getArguments().values()) {
            final String[] argNames = toArgNames(def);
            for (int i = 0; i < argNames.length; i++) {
                final CommandLine.Model.OptionSpec.Builder builder = createArgBuilder(def, argNames[i]);
                String argDisplaySuffix = "";
                String argName = argNames[i];
                String camelCaseArg = StringUtil.toCamelCase(argName.substring(2));
                if (!argName.equals("--" + camelCaseArg)) {
                    argDisplaySuffix = "\n[deprecated: --" + camelCaseArg + "]";
                }
                // 
                // Determine if this is a group command and set the property/environment display strings accordingly
                // 
                String description;
                if (commandDefinition.getName().length > 1) {
                    String propertyStringToPresent = "\n(liquibase.command." + StringUtil.join(commandDefinition.getName(), ".") + "." + def.getName() + ")";
                    String envStringToPresent = toEnvVariable("\n(liquibase.command." + StringUtil.join(commandDefinition.getName(), ".") + "." + def.getName()) + ")" + argDisplaySuffix;
                    description = propertyStringToPresent + envStringToPresent;
                } else {
                    description = "\n(liquibase.command." + def.getName() + " OR liquibase.command." + StringUtil.join(commandDefinition.getName(), ".") + "." + def.getName() + ")\n" + "(" + toEnvVariable("liquibase.command." + def.getName()) + " OR " + toEnvVariable("liquibase.command." + StringUtil.join(commandDefinition.getName(), ".") + "." + def.getName()) + ")" + argDisplaySuffix;
                }
                if (def.getDefaultValue() != null) {
                    if (def.getDefaultValueDescription() == null) {
                        description = "\nDEFAULT: " + def.getDefaultValue() + "\n" + description;
                    } else {
                        description = "\nDEFAULT: " + def.getDefaultValueDescription() + "\n" + description;
                    }
                }
                if (def.getDescription() != null) {
                    description = def.getDescription() + description;
                }
                if (def.isRequired()) {
                    description = "[REQUIRED] " + description;
                }
                builder.description(description + "\n");
                if (def.getDataType().equals(Boolean.class)) {
                    builder.arity("0..1");
                }
                if (i > 0) {
                    builder.hidden(true);
                } else {
                    builder.hidden(def.getHidden());
                }
                subCommandSpec.addOption(builder.build());
                if (argName.equals("--changelog-file")) {
                    final CommandLine.Model.OptionSpec.Builder paramBuilder = (CommandLine.Model.OptionSpec.Builder) CommandLine.Model.OptionSpec.builder("-D").required(false).type(HashMap.class).description("Pass a name/value pair for substitution in the changelog(s)\nPass as -D<property.name>=<property.value>\n[deprecated: set changelog properties in defaults file or environment variables]").mapFallbackValue("");
                    subCommandSpec.add(paramBuilder.build());
                }
            }
        }
        for (String legacyArg : legacyNoLongerCommandArguments) {
            final CommandLine.Model.OptionSpec.Builder builder = CommandLine.Model.OptionSpec.builder("--" + legacyArg).required(false).type(String.class).description("Legacy CLI argument").hidden(true);
            subCommandSpec.addOption(builder.build());
            String kabobArg = StringUtil.toKabobCase(legacyArg);
            if (!kabobArg.equals(legacyArg)) {
                final CommandLine.Model.OptionSpec.Builder kabobOptionBuilder = CommandLine.Model.OptionSpec.builder("--" + kabobArg).required(false).type(String.class).hidden(true).description("Legacy CLI argument");
                subCommandSpec.addOption(kabobOptionBuilder.build());
            }
        }
        getParentCommandSpec(commandDefinition, rootCommand).addSubcommand(commandName[commandName.length - 1], new CommandLine(subCommandSpec, defaultFactory));
    }
}
Also used : CommandLine(picocli.CommandLine)

Example 54 with CommandLine

use of picocli.CommandLine in project liquibase by liquibase.

the class CommandRunner method call.

@Override
public CommandResults call() throws Exception {
    List<String> command = new ArrayList<>();
    command.add(spec.commandLine().getCommandName());
    CommandLine parentCommand = spec.commandLine().getParent();
    while (!parentCommand.getCommandName().equals("liquibase")) {
        command.add(0, parentCommand.getCommandName());
        parentCommand = parentCommand.getParent();
    }
    final String[] commandName = LiquibaseCommandLine.getCommandNames(spec.commandLine());
    for (int i = 0; i < commandName.length; i++) {
        commandName[i] = StringUtil.toCamelCase(commandName[i]);
    }
    final CommandScope commandScope = new CommandScope(commandName);
    final File outputFile = LiquibaseCommandLineConfiguration.OUTPUT_FILE.getCurrentValue();
    OutputStream outputStream = null;
    try {
        if (outputFile != null) {
            outputStream = new FileOutputStream(outputFile);
            commandScope.setOutput(outputStream);
        }
        return commandScope.execute();
    } catch (CommandValidationException cve) {
        Throwable cause = cve.getCause();
        if (cause instanceof MissingRequiredArgumentException) {
            // This is a list of the arguments which the init project command supports. The thinking here is that if the user
            // forgets to supply one of these arguments, we're going to remind them about the init project command, which
            // can help them figure out what they should be providing here.
            final Set<String> initProjectArguments = Stream.of(CommonArgumentNames.CHANGELOG_FILE, CommonArgumentNames.URL, CommonArgumentNames.USERNAME, CommonArgumentNames.PASSWORD).map(CommonArgumentNames::getArgumentName).collect(Collectors.toSet());
            throw new CommandValidationException(cve.getMessage() + (initProjectArguments.contains(((MissingRequiredArgumentException) cause).getArgumentName()) ? ". If you need to configure new liquibase project files and arguments, run the 'liquibase init project' command." : ""));
        } else {
            throw cve;
        }
    } finally {
        if (outputStream != null) {
            outputStream.flush();
            outputStream.close();
        }
    }
}
Also used : Set(java.util.Set) CommandValidationException(liquibase.exception.CommandValidationException) OutputStream(java.io.OutputStream) FileOutputStream(java.io.FileOutputStream) ArrayList(java.util.ArrayList) CommandLine(picocli.CommandLine) MissingRequiredArgumentException(liquibase.exception.MissingRequiredArgumentException) FileOutputStream(java.io.FileOutputStream) CommandScope(liquibase.command.CommandScope) File(java.io.File) CommonArgumentNames(liquibase.command.CommonArgumentNames)

Example 55 with CommandLine

use of picocli.CommandLine in project neo4j by neo4j.

the class PushToCloudCommandTest method shouldAuthenticateBeforeDumping.

@Test
public void shouldAuthenticateBeforeDumping() throws CommandFailedException, IOException {
    // given
    Copier copier = mockedTargetCommunicator();
    DumpCreator dumper = mockedDumpCreator();
    PushToCloudCommand command = command().copier(copier).dumpCreator(dumper).build();
    // when
    String[] args = { "--bolt-uri", "bolt+routing://mydbid.databases.neo4j.io" };
    new CommandLine(command).execute(args);
    // then
    InOrder inOrder = inOrder(copier, dumper);
    inOrder.verify(copier).authenticate(anyBoolean(), anyString(), anyString(), any(), eq(false));
    inOrder.verify(dumper).dumpDatabase(anyString(), any());
    inOrder.verify(copier).copy(anyBoolean(), anyString(), eq("bolt+routing://mydbid.databases.neo4j.io"), any(), eq(true), anyString());
}
Also used : CommandLine(picocli.CommandLine) InOrder(org.mockito.InOrder) DumpCreator(org.neo4j.pushtocloud.PushToCloudCommand.DumpCreator) Copier(org.neo4j.pushtocloud.PushToCloudCommand.Copier) ArgumentMatchers.anyString(org.mockito.ArgumentMatchers.anyString) Test(org.junit.jupiter.api.Test)

Aggregations

CommandLine (picocli.CommandLine)68 Test (org.junit.jupiter.api.Test)22 ArgumentMatchers.anyString (org.mockito.ArgumentMatchers.anyString)20 Copier (org.neo4j.pushtocloud.PushToCloudCommand.Copier)17 ParseResult (picocli.CommandLine.ParseResult)12 Path (java.nio.file.Path)9 Test (org.junit.Test)9 IOException (java.io.IOException)8 Parameters (junitparams.Parameters)8 CommandSpec (picocli.CommandLine.Model.CommandSpec)6 PrintWriter (java.io.PrintWriter)5 DumpCreator (org.neo4j.pushtocloud.PushToCloudCommand.DumpCreator)5 ParameterException (picocli.CommandLine.ParameterException)4 HashMap (java.util.HashMap)3 List (java.util.List)3 Set (java.util.Set)3 OptionSpec (picocli.CommandLine.Model.OptionSpec)3 InputErrorException (eu.stamp_project.dspot.common.configuration.check.InputErrorException)2 File (java.io.File)2 PrintStream (java.io.PrintStream)2