Improvements to error messages
This commit is contained in:
parent
d269af1b70
commit
1a1c42c776
6 changed files with 174 additions and 97 deletions
|
@ -31,7 +31,7 @@
|
||||||
<packaging>pom</packaging>
|
<packaging>pom</packaging>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<quarkus.version>1.8.2.Final</quarkus.version>
|
<quarkus.version>1.9.0.CR1</quarkus.version>
|
||||||
<resteasy.version>4.5.6.Final</resteasy.version>
|
<resteasy.version>4.5.6.Final</resteasy.version>
|
||||||
<jackson.version>2.11.2</jackson.version>
|
<jackson.version>2.11.2</jackson.version>
|
||||||
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
<jackson.databind.version>${jackson.version}</jackson.databind.version>
|
||||||
|
|
|
@ -17,63 +17,80 @@
|
||||||
|
|
||||||
package org.keycloak.cli;
|
package org.keycloak.cli;
|
||||||
|
|
||||||
import static org.keycloak.cli.Picocli.createCommandSpec;
|
import static org.keycloak.cli.Picocli.createCommandLine;
|
||||||
|
import static org.keycloak.cli.Picocli.error;
|
||||||
import static org.keycloak.cli.Picocli.parseConfigArgs;
|
import static org.keycloak.cli.Picocli.parseConfigArgs;
|
||||||
|
import static org.keycloak.util.Environment.getProfileOrDefault;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.Quarkus;
|
||||||
import org.keycloak.common.Version;
|
import org.keycloak.common.Version;
|
||||||
|
|
||||||
import io.quarkus.runtime.Quarkus;
|
|
||||||
import io.quarkus.runtime.annotations.QuarkusMain;
|
import io.quarkus.runtime.annotations.QuarkusMain;
|
||||||
|
import org.keycloak.util.Environment;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The main entry point, responsible for initialize and run the CLI as well as start the server.
|
||||||
|
*/
|
||||||
@QuarkusMain(name = "keycloak")
|
@QuarkusMain(name = "keycloak")
|
||||||
public class KeycloakMain {
|
public class KeycloakMain {
|
||||||
|
|
||||||
public static void main(String args[]) {
|
public static void main(String cliArgs[]) {
|
||||||
System.setProperty("kc.version", Version.VERSION_KEYCLOAK);
|
System.setProperty("kc.version", Version.VERSION_KEYCLOAK);
|
||||||
|
CommandLine cmd = createCommandLine();
|
||||||
|
|
||||||
if (args.length != 0) {
|
if (cliArgs.length == 0) {
|
||||||
CommandLine cmd = new CommandLine(createCommandSpec());
|
// no arguments, just start the server
|
||||||
|
start(cmd);
|
||||||
cmd.setExecutionExceptionHandler(new CommandLine.IExecutionExceptionHandler() {
|
System.exit(cmd.getCommandSpec().exitCodeOnSuccess());
|
||||||
@Override
|
|
||||||
public int handleExecutionException(Exception ex, CommandLine commandLine,
|
|
||||||
CommandLine.ParseResult parseResult) {
|
|
||||||
commandLine.getErr().println(ex.getMessage());
|
|
||||||
commandLine.usage(commandLine.getErr());
|
|
||||||
return commandLine.getCommandSpec().exitCodeOnExecutionException();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
List<String> argsList = new LinkedList<>(Arrays.asList(args));
|
|
||||||
|
|
||||||
try {
|
|
||||||
System.setProperty("kc.config.args", parseConfigArgs(argsList));
|
|
||||||
CommandLine.ParseResult result = cmd.parseArgs(argsList.toArray(new String[argsList.size()]));
|
|
||||||
|
|
||||||
if (!result.hasSubcommand() && (!result.isUsageHelpRequested() && !result.isVersionHelpRequested())) {
|
|
||||||
argsList.add(0, "start");
|
|
||||||
}
|
|
||||||
} catch (CommandLine.UnmatchedArgumentException e) {
|
|
||||||
if (!cmd.getParseResult().hasSubcommand() && argsList.get(0).startsWith("--")) {
|
|
||||||
argsList.add(0, "start");
|
|
||||||
} else {
|
|
||||||
cmd.getErr().println(e.getMessage());
|
|
||||||
System.exit(CommandLine.ExitCode.SOFTWARE);
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
cmd.getErr().println(e.getMessage());
|
|
||||||
System.exit(CommandLine.ExitCode.SOFTWARE);
|
|
||||||
}
|
|
||||||
|
|
||||||
System.exit(cmd.execute(argsList.toArray(new String[argsList.size()])));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Quarkus.run(args);
|
// parse arguments and execute any of the configured commands
|
||||||
|
parseAndRun(cmd, cliArgs);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void start(CommandLine cmd) {
|
||||||
|
// We should use the method call below to start the server once Quarkus is released with https://github.com/quarkusio/quarkus/pull/12532.
|
||||||
|
// It will allow us to properly handle exception thrown during startup and at runtime.
|
||||||
|
// Quarkus.run(null, (integer, throwable) -> {
|
||||||
|
// error(cmd, String.format("Failed to start server using profile (%s).", getProfileOrDefault("none")), throwable.getCause());
|
||||||
|
// });
|
||||||
|
Quarkus.run(null, (integer) -> {
|
||||||
|
error(cmd, String.format("Failed to start server using profile (%s).", getProfileOrDefault("none")), null);
|
||||||
|
});
|
||||||
Quarkus.waitForExit();
|
Quarkus.waitForExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void parseAndRun(CommandLine cmd, String[] args) {
|
||||||
|
List<String> cliArgs = new LinkedList<>(Arrays.asList(args));
|
||||||
|
|
||||||
|
// set the arguments as a system property so that arguments can be mapped to their respective configuration options
|
||||||
|
System.setProperty("kc.config.args", parseConfigArgs(cliArgs));
|
||||||
|
|
||||||
|
try {
|
||||||
|
CommandLine.ParseResult result = cmd.parseArgs(cliArgs.toArray(new String[cliArgs.size()]));
|
||||||
|
|
||||||
|
// if no command was set, the start command becomes the default
|
||||||
|
if (!result.hasSubcommand() && (!result.isUsageHelpRequested() && !result.isVersionHelpRequested())) {
|
||||||
|
cliArgs.add(0, "start");
|
||||||
|
}
|
||||||
|
} catch (CommandLine.UnmatchedArgumentException e) {
|
||||||
|
// if no command was set but options were provided, the start command becomes the default
|
||||||
|
if (!cmd.getParseResult().hasSubcommand() && cliArgs.get(0).startsWith("--")) {
|
||||||
|
cliArgs.add(0, "start");
|
||||||
|
} else {
|
||||||
|
cmd.getErr().println(e.getMessage());
|
||||||
|
System.exit(cmd.getCommandSpec().exitCodeOnInvalidInput());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
cmd.getErr().println(e.getMessage());
|
||||||
|
System.exit(cmd.getCommandSpec().exitCodeOnExecutionException());
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(cmd.execute(cliArgs.toArray(new String[cliArgs.size()])));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,13 @@
|
||||||
|
|
||||||
package org.keycloak.cli;
|
package org.keycloak.cli;
|
||||||
|
|
||||||
|
import static org.keycloak.cli.Picocli.error;
|
||||||
|
import static org.keycloak.cli.Picocli.errorAndExit;
|
||||||
|
import static org.keycloak.cli.Picocli.println;
|
||||||
|
|
||||||
import org.keycloak.configuration.KeycloakConfigSourceProvider;
|
import org.keycloak.configuration.KeycloakConfigSourceProvider;
|
||||||
|
|
||||||
import io.quarkus.bootstrap.runner.QuarkusEntryPoint;
|
import io.quarkus.bootstrap.runner.QuarkusEntryPoint;
|
||||||
import io.quarkus.runtime.Quarkus;
|
|
||||||
import org.keycloak.util.Environment;
|
import org.keycloak.util.Environment;
|
||||||
import picocli.CommandLine;
|
import picocli.CommandLine;
|
||||||
import picocli.CommandLine.Command;
|
import picocli.CommandLine.Command;
|
||||||
|
@ -68,30 +71,15 @@ public class MainCommand {
|
||||||
usageHelpAutoWidth = true,
|
usageHelpAutoWidth = true,
|
||||||
optionListHeading = "%nOptions%n",
|
optionListHeading = "%nOptions%n",
|
||||||
parameterListHeading = "Available Commands%n")
|
parameterListHeading = "Available Commands%n")
|
||||||
public void reAugment(@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean debug) {
|
public void reAugment(@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("quarkus.launch.rebuild", "true");
|
System.setProperty("quarkus.launch.rebuild", "true");
|
||||||
println("Updating the configuration and installing your custom providers, if any. Please wait.");
|
println(spec.commandLine(), "Updating the configuration and installing your custom providers, if any. Please wait.");
|
||||||
try {
|
try {
|
||||||
QuarkusEntryPoint.main();
|
QuarkusEntryPoint.main();
|
||||||
println("Server configuration updated and persisted. Run the following command to review the configuration:\n");
|
println(spec.commandLine(), "Server configuration updated and persisted. Run the following command to review the configuration:\n");
|
||||||
println("\t" + Environment.getCommand() + " show-config\n");
|
println(spec.commandLine(), "\t" + Environment.getCommand() + " show-config\n");
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
String message = throwable.getMessage();
|
error(spec.commandLine(), "Failed to update server configuration.", throwable);
|
||||||
Throwable cause = throwable.getCause();
|
|
||||||
|
|
||||||
if (cause != null) {
|
|
||||||
message = cause.getMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
error("Failed to update server configuration: " + message);
|
|
||||||
|
|
||||||
if (debug == null) {
|
|
||||||
errorAndExit("For more details run the same command passing the '--verbose' option.");
|
|
||||||
} else {
|
|
||||||
error("Details:");
|
|
||||||
throwable.printStackTrace();
|
|
||||||
System.exit(spec.exitCodeOnExecutionException());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,10 +88,10 @@ public class MainCommand {
|
||||||
mixinStandardHelpOptions = true,
|
mixinStandardHelpOptions = true,
|
||||||
optionListHeading = "%nOptions%n",
|
optionListHeading = "%nOptions%n",
|
||||||
parameterListHeading = "Available Commands%n")
|
parameterListHeading = "Available Commands%n")
|
||||||
public void startDev() {
|
public void startDev(@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("kc.profile", "dev");
|
System.setProperty("kc.profile", "dev");
|
||||||
System.setProperty("quarkus.profile", "dev");
|
System.setProperty("quarkus.profile", "dev");
|
||||||
start();
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "export",
|
@Command(name = "export",
|
||||||
|
@ -116,7 +104,8 @@ public class MainCommand {
|
||||||
@Option(names = "--file", arity = "1", description = "Set the path to a file that will be created with the exported data.", paramLabel = "<path>") String toFile,
|
@Option(names = "--file", arity = "1", description = "Set the path to a file that will be created with the exported data.", paramLabel = "<path>") String toFile,
|
||||||
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to export", paramLabel = "<realm>") String realm,
|
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to export", paramLabel = "<realm>") String realm,
|
||||||
@Option(names = "--users", arity = "1", description = "Set how users should be exported. Possible values are: skip, realm_file, same_file, different_files.", paramLabel = "<strategy>", defaultValue = "different_files") String users,
|
@Option(names = "--users", arity = "1", description = "Set how users should be exported. Possible values are: skip, realm_file, same_file, different_files.", paramLabel = "<strategy>", defaultValue = "different_files") String users,
|
||||||
@Option(names = "--users-per-file", arity = "1", description = "Set the number of users per file. It’s used only if --users=different_files.", paramLabel = "<number>", defaultValue = "50") Integer usersPerFile) {
|
@Option(names = "--users-per-file", arity = "1", description = "Set the number of users per file. It’s used only if --users=different_files.", paramLabel = "<number>", defaultValue = "50") Integer usersPerFile,
|
||||||
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("keycloak.migration.action", "export");
|
System.setProperty("keycloak.migration.action", "export");
|
||||||
|
|
||||||
if (toDir != null) {
|
if (toDir != null) {
|
||||||
|
@ -126,7 +115,7 @@ public class MainCommand {
|
||||||
System.setProperty("keycloak.migration.provider", "singleFile");
|
System.setProperty("keycloak.migration.provider", "singleFile");
|
||||||
System.setProperty("keycloak.migration.file", toFile);
|
System.setProperty("keycloak.migration.file", toFile);
|
||||||
} else {
|
} else {
|
||||||
errorAndExit("Must specify either --dir or --file options.");
|
errorAndExit(spec.commandLine(), "Must specify either --dir or --file options.");
|
||||||
}
|
}
|
||||||
|
|
||||||
System.setProperty("keycloak.migration.usersExportStrategy", users.toUpperCase());
|
System.setProperty("keycloak.migration.usersExportStrategy", users.toUpperCase());
|
||||||
|
@ -138,7 +127,7 @@ public class MainCommand {
|
||||||
if (realm != null) {
|
if (realm != null) {
|
||||||
System.setProperty("keycloak.migration.realmName", realm);
|
System.setProperty("keycloak.migration.realmName", realm);
|
||||||
}
|
}
|
||||||
start();
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "import",
|
@Command(name = "import",
|
||||||
|
@ -150,7 +139,8 @@ public class MainCommand {
|
||||||
public void runImport(@Option(names = "--dir", arity = "1", description = "Set the path to a directory containing the files with the data to import", paramLabel = "<path>") String toDir,
|
public void runImport(@Option(names = "--dir", arity = "1", description = "Set the path to a directory containing the files with the data to import", paramLabel = "<path>") String toDir,
|
||||||
@Option(names = "--file", arity = "1", description = "Set the path to a file with the data to import.", paramLabel = "<path>") String toFile,
|
@Option(names = "--file", arity = "1", description = "Set the path to a file with the data to import.", paramLabel = "<path>") String toFile,
|
||||||
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to import", paramLabel = "<realm>") String realm,
|
@Option(names = "--realm", arity = "1", description = "Set the name of the realm to import", paramLabel = "<realm>") String realm,
|
||||||
@Option(names = "--override", arity = "1", description = "Set if existing data should be skipped or overridden.", paramLabel = "false", defaultValue = "true") boolean override) {
|
@Option(names = "--override", arity = "1", description = "Set if existing data should be skipped or overridden.", paramLabel = "false", defaultValue = "true") boolean override,
|
||||||
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("keycloak.migration.action", "import");
|
System.setProperty("keycloak.migration.action", "import");
|
||||||
if (toDir != null) {
|
if (toDir != null) {
|
||||||
System.setProperty("keycloak.migration.provider", "dir");
|
System.setProperty("keycloak.migration.provider", "dir");
|
||||||
|
@ -159,7 +149,7 @@ public class MainCommand {
|
||||||
System.setProperty("keycloak.migration.provider", "singleFile");
|
System.setProperty("keycloak.migration.provider", "singleFile");
|
||||||
System.setProperty("keycloak.migration.file", toFile);
|
System.setProperty("keycloak.migration.file", toFile);
|
||||||
} else {
|
} else {
|
||||||
errorAndExit("Must specify either --dir or --file options.");
|
errorAndExit(spec.commandLine(), "Must specify either --dir or --file options.");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (realm != null) {
|
if (realm != null) {
|
||||||
|
@ -168,7 +158,7 @@ public class MainCommand {
|
||||||
|
|
||||||
System.setProperty("keycloak.migration.strategy", override ? "OVERWRITE_EXISTING" : "IGNORE_EXISTING");
|
System.setProperty("keycloak.migration.strategy", override ? "OVERWRITE_EXISTING" : "IGNORE_EXISTING");
|
||||||
|
|
||||||
start();
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "start",
|
@Command(name = "start",
|
||||||
|
@ -179,14 +169,15 @@ public class MainCommand {
|
||||||
parameterListHeading = "Available Commands%n")
|
parameterListHeading = "Available Commands%n")
|
||||||
public void start(
|
public void start(
|
||||||
@CommandLine.Parameters(paramLabel = "show-config", arity = "0..1",
|
@CommandLine.Parameters(paramLabel = "show-config", arity = "0..1",
|
||||||
description = "Print out the configuration options when starting the server.") String showConfig) {
|
description = "Print out the configuration options when starting the server.") String showConfig,
|
||||||
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
if ("show-config".equals(showConfig)) {
|
if ("show-config".equals(showConfig)) {
|
||||||
System.setProperty("kc.show.config.runtime", Boolean.TRUE.toString());
|
System.setProperty("kc.show.config.runtime", Boolean.TRUE.toString());
|
||||||
System.setProperty("kc.show.config", "all");
|
System.setProperty("kc.show.config", "all");
|
||||||
} else if (showConfig != null) {
|
} else if (showConfig != null) {
|
||||||
throw new CommandLine.UnmatchedArgumentException(spec.commandLine(), "Invalid argument: " + showConfig);
|
throw new CommandLine.UnmatchedArgumentException(spec.commandLine(), "Invalid argument: " + showConfig);
|
||||||
}
|
}
|
||||||
start();
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Command(name = "show-config",
|
@Command(name = "show-config",
|
||||||
|
@ -195,26 +186,9 @@ public class MainCommand {
|
||||||
optionListHeading = "%nOptions%n",
|
optionListHeading = "%nOptions%n",
|
||||||
parameterListHeading = "Available Commands%n")
|
parameterListHeading = "Available Commands%n")
|
||||||
public void showConfiguration(
|
public void showConfiguration(
|
||||||
@CommandLine.Parameters(paramLabel = "filter", defaultValue = "none", description = "Show all configuration options. Use 'all' to show all options.") String filter) {
|
@CommandLine.Parameters(paramLabel = "filter", defaultValue = "none", description = "Show all configuration options. Use 'all' to show all options.") String filter,
|
||||||
|
@Option(names = "--verbose", description = "Print out more details when running this command.", required = false) Boolean verbose) {
|
||||||
System.setProperty("kc.show.config", filter);
|
System.setProperty("kc.show.config", filter);
|
||||||
start();
|
KeycloakMain.start(spec.commandLine());
|
||||||
}
|
|
||||||
|
|
||||||
private void start() {
|
|
||||||
Quarkus.run();
|
|
||||||
Quarkus.waitForExit();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void println(String message) {
|
|
||||||
spec.commandLine().getOut().println(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void errorAndExit(String message) {
|
|
||||||
error(message);
|
|
||||||
System.exit(CommandLine.ExitCode.SOFTWARE);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void error(String message) {
|
|
||||||
spec.commandLine().getErr().println(message);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,12 @@
|
||||||
package org.keycloak.cli;
|
package org.keycloak.cli;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.IntFunction;
|
import java.util.function.IntFunction;
|
||||||
|
|
||||||
|
import io.quarkus.runtime.Quarkus;
|
||||||
import org.keycloak.common.Profile;
|
import org.keycloak.common.Profile;
|
||||||
import org.keycloak.configuration.PropertyMapper;
|
import org.keycloak.configuration.PropertyMapper;
|
||||||
import org.keycloak.configuration.PropertyMappers;
|
import org.keycloak.configuration.PropertyMappers;
|
||||||
|
@ -30,11 +32,12 @@ import picocli.CommandLine;
|
||||||
|
|
||||||
final class Picocli {
|
final class Picocli {
|
||||||
|
|
||||||
static CommandLine.Model.CommandSpec createCommandSpec() {
|
static CommandLine createCommandLine() {
|
||||||
CommandLine.Model.CommandSpec spec = CommandLine.Model.CommandSpec.forAnnotatedObject(new MainCommand())
|
CommandLine.Model.CommandSpec spec = CommandLine.Model.CommandSpec.forAnnotatedObject(new MainCommand())
|
||||||
.name(Environment.getCommand());
|
.name(Environment.getCommand());
|
||||||
|
|
||||||
addOption(spec, "start", PropertyMappers.getRuntimeMappers());
|
addOption(spec, "start", PropertyMappers.getRuntimeMappers());
|
||||||
|
addOption(spec, "start-dev", PropertyMappers.getRuntimeMappers());
|
||||||
addOption(spec, "config", PropertyMappers.getRuntimeMappers());
|
addOption(spec, "config", PropertyMappers.getRuntimeMappers());
|
||||||
addOption(spec, "config", PropertyMappers.getBuiltTimeMappers());
|
addOption(spec, "config", PropertyMappers.getBuiltTimeMappers());
|
||||||
addOption(spec.subcommands().get("config").getCommandSpec(), "--features", "Enables a group of features. Possible values are: "
|
addOption(spec.subcommands().get("config").getCommandSpec(), "--features", "Enables a group of features. Possible values are: "
|
||||||
|
@ -45,7 +48,20 @@ final class Picocli {
|
||||||
addOption(spec.subcommands().get("config").getCommandSpec(), "--features-" + feature.name().toLowerCase(),
|
addOption(spec.subcommands().get("config").getCommandSpec(), "--features-" + feature.name().toLowerCase(),
|
||||||
"Enables the " + feature.name() + " feature. Set enabled to enable the feature or disabled otherwise.");
|
"Enables the " + feature.name() + " feature. Set enabled to enable the feature or disabled otherwise.");
|
||||||
}
|
}
|
||||||
return spec;
|
|
||||||
|
CommandLine cmd = new CommandLine(spec);
|
||||||
|
|
||||||
|
cmd.setExecutionExceptionHandler(new CommandLine.IExecutionExceptionHandler() {
|
||||||
|
@Override
|
||||||
|
public int handleExecutionException(Exception ex, CommandLine commandLine,
|
||||||
|
CommandLine.ParseResult parseResult) {
|
||||||
|
commandLine.getErr().println(ex.getMessage());
|
||||||
|
commandLine.usage(commandLine.getErr());
|
||||||
|
return commandLine.getCommandSpec().exitCodeOnExecutionException();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static String parseConfigArgs(List<String> argsList) {
|
static String parseConfigArgs(List<String> argsList) {
|
||||||
|
@ -92,4 +108,47 @@ final class Picocli {
|
||||||
.paramLabel("<value>")
|
.paramLabel("<value>")
|
||||||
.type(String.class).build());
|
.type(String.class).build());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static List<String> getCliArgs(CommandLine cmd) {
|
||||||
|
CommandLine.ParseResult parseResult = cmd.getParseResult();
|
||||||
|
|
||||||
|
if (parseResult == null) {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
return parseResult.expandedArgs();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void errorAndExit(CommandLine cmd, String message) {
|
||||||
|
error(cmd, message, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void error(CommandLine cmd, String message, Throwable throwable) {
|
||||||
|
List<String> cliArgs = getCliArgs(cmd);
|
||||||
|
|
||||||
|
cmd.getErr().println("ERROR: " + message);
|
||||||
|
|
||||||
|
if (throwable != null) {
|
||||||
|
Throwable cause = throwable;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (cause.getMessage() != null) {
|
||||||
|
cmd.getErr().println(String.format("ERROR: %s", cause.getMessage()));
|
||||||
|
}
|
||||||
|
} while ((cause = cause.getCause())!= null);
|
||||||
|
|
||||||
|
if (cliArgs.stream().anyMatch((arg) -> "--verbose".equals(arg))) {
|
||||||
|
cmd.getErr().println("ERROR: Details:");
|
||||||
|
throwable.printStackTrace();
|
||||||
|
} else {
|
||||||
|
cmd.getErr().println("For more details run the same command passing the '--verbose' option.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.exit(cmd.getCommandSpec().exitCodeOnExecutionException());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void println(CommandLine cmd, String message) {
|
||||||
|
cmd.getOut().println(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,9 +109,9 @@ public final class PropertyMappers {
|
||||||
case "postgres-10":
|
case "postgres-10":
|
||||||
return "io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect";
|
return "io.quarkus.hibernate.orm.runtime.dialect.QuarkusPostgreSQL10Dialect";
|
||||||
}
|
}
|
||||||
throw invalidDatabaseVendor(db, "h2-file", "h2-mem", "mariadb", "postgres", "postgres-95", "postgres-10");
|
return null;
|
||||||
}, "The database vendor. Possible values are: h2-mem, h2-file, mariadb, postgres95, postgres10.");
|
}, null);
|
||||||
create("db", "quarkus.datasource.driver", (db, context) -> {
|
create("db", "quarkus.datasource.jdbc.driver", (db, context) -> {
|
||||||
switch (db.toLowerCase()) {
|
switch (db.toLowerCase()) {
|
||||||
case "h2-file":
|
case "h2-file":
|
||||||
case "h2-mem":
|
case "h2-mem":
|
||||||
|
@ -124,8 +124,21 @@ public final class PropertyMappers {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}, null);
|
}, null);
|
||||||
|
create("db", "quarkus.datasource.db-kind", (db, context) -> {
|
||||||
|
switch (db.toLowerCase()) {
|
||||||
|
case "h2-file":
|
||||||
|
case "h2-mem":
|
||||||
|
return "h2";
|
||||||
|
case "mariadb":
|
||||||
|
return "mariadb";
|
||||||
|
case "postgres-95":
|
||||||
|
case "postgres-10":
|
||||||
|
return "postgresql";
|
||||||
|
}
|
||||||
|
throw invalidDatabaseVendor(db, "h2-file", "h2-mem", "mariadb", "postgres", "postgres-95", "postgres-10");
|
||||||
|
}, "The database vendor. Possible values are: h2-mem, h2-file, mariadb, postgres95, postgres10.");
|
||||||
create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null);
|
create("db", "quarkus.datasource.jdbc.transactions", (db, context) -> "xa", null);
|
||||||
create("db.url", "db", "quarkus.datasource.url", (db, context) -> {
|
create("db.url", "db", "quarkus.datasource.jdbc.url", (db, context) -> {
|
||||||
switch (db.toLowerCase()) {
|
switch (db.toLowerCase()) {
|
||||||
case "h2-file":
|
case "h2-file":
|
||||||
return "jdbc:h2:file:${kc.home.dir:${kc.db.url.path:~}}/${kc.data.dir:data}/keycloakdb${kc.db.url.properties:;;AUTO_SERVER=TRUE}";
|
return "jdbc:h2:file:${kc.home.dir:${kc.db.url.path:~}}/${kc.data.dir:data}/keycloakdb${kc.db.url.properties:;;AUTO_SERVER=TRUE}";
|
||||||
|
|
|
@ -56,6 +56,20 @@ public final class Environment {
|
||||||
return profile;
|
return profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getProfileOrDefault(String defaultProfile) {
|
||||||
|
String profile = System.getProperty("kc.profile");
|
||||||
|
|
||||||
|
if (profile == null) {
|
||||||
|
profile = System.getenv("KC_PROFILE");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile == null) {
|
||||||
|
profile = defaultProfile;
|
||||||
|
}
|
||||||
|
|
||||||
|
return profile;
|
||||||
|
}
|
||||||
|
|
||||||
public static Optional<String> getBuiltTimeProperty(String name) {
|
public static Optional<String> getBuiltTimeProperty(String name) {
|
||||||
String value = KeycloakRecorder.getBuiltTimeProperty(name);
|
String value = KeycloakRecorder.getBuiltTimeProperty(name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue