Skip to content

Commit

Permalink
Merge pull request #13 from jfdenise/cli-v2
Browse files Browse the repository at this point in the history
Re-work CLI
  • Loading branch information
jfdenise authored Oct 19, 2023
2 parents e23d6a6 + 1d812fa commit a3688e7
Show file tree
Hide file tree
Showing 28 changed files with 1,037 additions and 152 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,28 +48,28 @@ to adjust the provisioned WildFly server (execution context, profile, add-ons, W

* To display the required Galleon layers and feature-packs required to run kitchensink:

`java -jar cli/target/wildfly-glow.jar examples/war/kitchensink.war`
`./wildfly-glow scan examples/war/kitchensink.war`

* To display the required Galleon layers and feature-packs required to run kitchensink on the cloud:

`java -jar cli/target/wildfly-glow.jar examples/war/kitchensink.war --context=cloud`
`./wildfly-glow scan examples/war/kitchensink.war --cloud`

* To provision a WildFly server to run kitchensink:

`java -jar cli/target/wildfly-glow.jar examples/war/kitchensink.war --output=server`
`./wildfly-glow scan examples/war/kitchensink.war --provision=server`

* To provision a WildFly Bootable JAR to run kitchensink:

`java -jar cli/target/wildfly-glow.jar examples/war/kitchensink.war --output=bootable-jar`
`./wildfly-glow scan examples/war/kitchensink.war --provision=bootable-jar`

* To provision a WildFly server for the cloud and produce a Docker image to run kitchensink:

`java -jar cli/target/wildfly-glow.jar examples/war/kitchensink.war --output=server --context=cloud`
`./wildfly-glow scan examples/war/kitchensink.war --provision=server --cloud`


# Accessing the WildFly Glow command line help

`java -jar cli/target/wildfly-glow.jar --help`
`./wildfly-glow --help`

# WildFly Glow documentation

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
ProvisioningXmlWriter.getInstance().write(builder.build(), fileWriter);
}
} else {
results.outputConfig(outputFolder, false);
results.outputConfig(outputFolder, null);
}
} catch (Exception ex) {
if (ex instanceof MojoExecutionException) {
Expand Down
4 changes: 4 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
<groupId>${project.groupId}</groupId>
<artifactId>wildfly-glow-core</artifactId>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
</dependency>
<!-- to fix slf4j warning when provisioning -->
<dependency>
<groupId>org.jboss.slf4j</groupId>
Expand Down
50 changes: 31 additions & 19 deletions cli/src/main/java/org/wildfly/glow/cli/CLIArguments.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,14 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import org.jboss.galleon.config.FeaturePackConfig;
import org.jboss.galleon.config.ProvisioningConfig;
import org.wildfly.glow.AddOn;
import org.jboss.galleon.universe.FeaturePackLocation;
import org.wildfly.glow.Arguments;
import org.wildfly.glow.FeaturePacks;
import static org.wildfly.glow.GlowSession.STANDALONE_PROFILE;
Expand Down Expand Up @@ -62,7 +63,7 @@ public class CLIArguments extends Arguments {
private final boolean help;
private final boolean version;
private final boolean displayConfigurationInfo;
private CLIArguments(
public CLIArguments(
boolean version,
boolean help,
String executionContext,
Expand Down Expand Up @@ -303,30 +304,41 @@ public static void dumpInfos(Set<String> profiles) throws Exception {
System.out.println(builder);
}

public static void dumpConfiguration(String context, String serverVersion, Map<String, Layer> allLayers,
public static String dumpConfiguration(Map<FeaturePackLocation.FPID, Set<FeaturePackLocation.ProducerSpec>> fpDependencies, String context, String serverVersion, Map<String, Layer> allLayers,
LayerMapping mapping, ProvisioningConfig fps, boolean isLatest, boolean techPreview) throws Exception {
StringBuilder builder = new StringBuilder();
builder.append("\n Execution context: ").append(context).append("\n");
builder.append("\n Server version: ").append(serverVersion).append(isLatest ? " (latest)" : "").append("\n");
builder.append("\n Tech Preview: ").append(techPreview).append("\n");
builder.append("\n Known Galleon feature-packs:\n");
builder.append("Execution context: ").append(context).append("\n");
builder.append("Server version: ").append(serverVersion).append(isLatest ? " (latest)" : "").append("\n");
builder.append("Tech Preview: ").append(techPreview).append("\n");
Set<FeaturePackLocation.ProducerSpec> topLevel = new LinkedHashSet<>();
for(FeaturePackConfig fp : fps.getFeaturePackDeps()) {
builder.append(" * ").append(fp.getLocation().getFPID()).append("\n");
topLevel.add(fp.getLocation().getProducer());
}
builder.append("\n Possible add-ons:\n");
for (Map.Entry<String, Set<AddOn>> entry : mapping.getAddOnFamilyMembers().entrySet()) {
builder.append(" * ").append(entry.getKey()).append(" add-ons:\n");
for (AddOn member : mapping.getAddOnFamilyMembers().get(entry.getKey())) {
if (!member.getName().endsWith(":default")) {
builder.append(" - ").append(member.getName()).append(member.getDescription() == null ? "" : ": " + member.getDescription()).append("\n");
for(FeaturePackConfig fp : fps.getFeaturePackDeps()) {
builder.append("\nFeature-pack: ").append("@|bold ").append(fp.getLocation().getFPID()).append("|@\n");
builder.append("Contained layers: ");
Set<String> layers = new TreeSet<>();
Set<FeaturePackLocation.ProducerSpec> deps = fpDependencies.get(fp.getLocation().getFPID());
for(Layer l : allLayers.values()) {
if(l.getFeaturePacks().contains(fp.getLocation().getFPID())) {
layers.add(l.getName());
}
if(deps != null) {
for (FeaturePackLocation.ProducerSpec dep : deps) {
if (!topLevel.contains(dep)) {
for (FeaturePackLocation.FPID fpid : l.getFeaturePacks()) {
if (fpid.getProducer().equals(dep)) {
layers.add(l.getName());
}
}
}
}
}
}
topLevel.addAll(deps);
builder.append(layers).append("\n");
}
builder.append("\n Known Galleon layers:\n");
Set<String> sortedSet = new TreeSet<>();
sortedSet.addAll(allLayers.keySet());
builder.append(sortedSet).append("\n");
System.out.println(builder.toString());
return builder.toString();
}

public boolean isGoOffline() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates
* and other contributors as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.wildfly.glow.cli;

import picocli.CommandLine;


/**
* Handles exceptions that happen during command executions.
*/
public class ExecutionExceptionHandler implements CommandLine.IExecutionExceptionHandler {

private final boolean isVerbose;

public ExecutionExceptionHandler(boolean isVerbose) {
this.isVerbose = isVerbose;
}

@Override
public int handleExecutionException(Exception ex, CommandLine commandLine, CommandLine.ParseResult parseResult)
throws Exception {
System.err.println(CommandLine.Help.Ansi.AUTO.string("@|fg(red) ERROR: " + ex.getLocalizedMessage() + "|@"));
if(isVerbose) {
ex.printStackTrace();
}
return 1;
}

}
30 changes: 28 additions & 2 deletions cli/src/main/java/org/wildfly/glow/cli/GlowCLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import org.jboss.galleon.layout.FeaturePackLayout;
import org.jboss.galleon.layout.ProvisioningLayout;
import org.jboss.galleon.universe.UniverseResolver;
Expand All @@ -42,6 +43,14 @@
import org.wildfly.glow.Version;

import static org.wildfly.glow.GlowSession.OFFLINE_CONTENT;
import org.wildfly.glow.cli.commands.CompletionCommand;
import org.wildfly.glow.cli.commands.GoOfflineCommand;
import org.wildfly.glow.cli.commands.ShowConfigurationCommand;
import org.wildfly.glow.cli.commands.MainCommand;
import org.wildfly.glow.cli.commands.ScanCommand;
import org.wildfly.glow.cli.commands.ShowAddOnsCommand;
import org.wildfly.glow.cli.commands.ShowServerVersionsCommand;
import picocli.CommandLine;

/**
*
Expand All @@ -50,6 +59,23 @@
public class GlowCLI {

public static void main(String[] args) throws Exception {
try {
CommandLine commandLine = new CommandLine(new MainCommand());
commandLine.addSubcommand(new ScanCommand());
commandLine.addSubcommand(new ShowAddOnsCommand());
commandLine.addSubcommand(new ShowServerVersionsCommand());
commandLine.addSubcommand(new ShowConfigurationCommand());
commandLine.addSubcommand(new GoOfflineCommand());
commandLine.addSubcommand(new CompletionCommand());
commandLine.setUsageHelpAutoWidth(true);
final boolean isVerbose = Arrays.stream(args).anyMatch(s -> s.equals("-vv") || s.equals("--verbose"));
commandLine.setExecutionExceptionHandler(new ExecutionExceptionHandler(isVerbose));
int exitCode = commandLine.execute(args);
System.exit(exitCode);
} catch (Exception ex) {
System.err.println(ex.getMessage());
System.exit(1);
}
CLIArguments arguments = CLIArguments.fromMainArguments(args);
if (arguments.isVersion()) {
System.out.println(Version.getVersion());
Expand All @@ -76,7 +102,7 @@ public static void main(String[] args) throws Exception {
String serverVersion = isLatest ? FeaturePacks.getLatestVersion() : arguments.getVersion();
Path fps = FeaturePacks.getFeaturePacks(serverVersion, arguments.getExecutionContext(), arguments.isTechPreview());
ProvisioningConfig config = ProvisioningXmlParser.parse(fps);
CLIArguments.dumpConfiguration(arguments.getExecutionContext(), serverVersion, all, mapping, config, isLatest, arguments.isTechPreview());
CLIArguments.dumpConfiguration(null, arguments.getExecutionContext(), serverVersion, all, mapping, config, isLatest, arguments.isTechPreview());
}
} finally {
IoUtils.recursiveDelete(OFFLINE_CONTENT);
Expand All @@ -92,7 +118,7 @@ public static void main(String[] args) throws Exception {
if (arguments.getOutput() == null) {
scanResults.outputInformation();
} else {
scanResults.outputConfig(Paths.get("server"), true);
scanResults.outputConfig(Paths.get("server"), null);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2023 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.glow.cli.commands;

import java.util.Optional;
import java.util.concurrent.Callable;

import picocli.CommandLine;

public abstract class AbstractCommand implements Callable<Integer> {

@SuppressWarnings("unused")
@CommandLine.Option(
names = {Constants.HELP_OPTION_SHORT, Constants.HELP_OPTION},
usageHelp = true
)
boolean help;

@SuppressWarnings("unused")
@CommandLine.Option(
names = {Constants.VERBOSE_OPTION_SHORT, Constants.VERBOSE_OPTION}
)
Optional<Boolean> verbose;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* JBoss, Home of Professional Open Source.
* Copyright 2023 Red Hat, Inc., and individual contributors
* as indicated by the @author tags.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.wildfly.glow.cli.commands;

import picocli.AutoComplete;
import picocli.CommandLine;

/**
* By invoking this command, user can obtain a shell completion script.
*
* User can apply the completion script by running `source <(wildfly-glow completion)` (in bash), or can redirect the
* output of this command to a file.
*
* The completion script can be used for bash and zsh.
*/
@CommandLine.Command(
name = Constants.COMPLETION_COMMAND,
mixinStandardHelpOptions = true,
helpCommand = true)
public class CompletionCommand implements Runnable {

@CommandLine.Spec
CommandLine.Model.CommandSpec spec;

@Override
public void run() {
String script = AutoComplete.bash(Constants.WILDFLY_GLOW, spec.root().commandLine());
spec.commandLine().getOut().print(script);
spec.commandLine().getOut().print('\n');
spec.commandLine().getOut().flush();
}
}
Loading

0 comments on commit a3688e7

Please sign in to comment.