From ee58a2ceca68f318702af03d2765a0141cb9fe1b Mon Sep 17 00:00:00 2001 From: Ivan Garcia Sainz-Aja Date: Tue, 28 Mar 2023 21:13:45 +0100 Subject: [PATCH] Improves Help command. --- .../src/main/java/io/zenwave360/sdk/Help.java | 4 +- .../src/main/java/io/zenwave360/sdk/Main.java | 69 +++++++++++++------ .../main/java/io/zenwave360/sdk/Plugin.java | 7 ++ .../sdk/writers/TemplateFileWriter.java | 8 ++- .../resources/io/zenwave360/sdk/help/list.hbs | 2 + .../test/java/io/zenwave360/sdk/HelpTest.java | 17 ++++- .../io/zenwave360/sdk/MainGeneratorTest.java | 3 +- .../test/java/io/zenwave360/sdk/MainTest.java | 1 + 8 files changed, 85 insertions(+), 26 deletions(-) diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Help.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Help.java index 11c86ea4..f5e0c4ca 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Help.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Help.java @@ -24,11 +24,12 @@ import io.zenwave360.sdk.templating.HandlebarsEngine; import io.zenwave360.sdk.templating.TemplateInput; import io.zenwave360.sdk.utils.Maps; +import picocli.CommandLine; public class Help { enum Format { - help, detailed, json, markdown, html, list + list, help, detailed, json, markdown, html; } private ObjectMapper objectMapper = new ObjectMapper(); @@ -116,6 +117,7 @@ protected Map asModel(Object plugin, Field field, DocumentedOpti } public String help(Plugin plugin, Format format) { + format = format == null ? Format.help : format; var model = format == Format.list ? discoverAvailablePlugins() : buildHelpModel(plugin); model.put("version", getClass().getPackage().getImplementationVersion()); if (format == Format.json) { diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Main.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Main.java index e8bc6365..818e3da9 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Main.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Main.java @@ -17,18 +17,18 @@ public class Main implements Callable { private Logger log = LoggerFactory.getLogger(getClass()); - @Option(names = {"-h", "--help"}, usageHelp = true, description = "display this help message") - boolean help; - - @Option(names = {"-f", "--help-format"}, arity = "0..1", description = "Help output format", defaultValue = "help") - Help.Format helpFormat = Help.Format.help; + @Option(names = {"-h", "--help"}, arity = "0..1", description = "Help with output format", converter = HelpFormatConverter.class) + Help.Format helpFormat; @Option(names = {"-p", "--plugin"}, arity = "0..1", description = "Plugin Class or short-code") - String pluginConfigClass; + String pluginClass; - @Option(names = {"-c", "--chain"}, split = ",", description = " use --plugin instead") + @Option(names = {"-c", "--chain"}, split = ",", description = " use --plugin instead", hidden = true) Class[] chain; + @Option(names = {"-f", "--force"}, description = "Force overwrite", defaultValue = "false") + boolean forceOverwrite = false; + @CommandLine.Parameters Map options = new HashMap<>(); @@ -37,14 +37,21 @@ public static void main(String... args) { CommandLine cmd = new CommandLine(main); CommandLine.ParseResult parsed = cmd.parseArgs(args); - if (parsed.hasMatchedOption("h") && (parsed.hasMatchedOption("p") || parsed.hasMatchedOption("f"))) { - try { - main.help(); - } catch (Exception e) { - e.printStackTrace(); - } + boolean noOptions = !parsed.hasMatchedOption("h") && !parsed.hasMatchedOption("p"); + boolean noPlugin = !parsed.hasMatchedOption("p"); + boolean usage = parsed.hasMatchedOption("h") && !parsed.hasMatchedOption("p") && main.helpFormat == null; + + if(usage || noOptions || noPlugin) { + cmd.usage(System.out); + main.helpFormat = Help.Format.list; + main.help(); return; } + if (parsed.hasMatchedOption("h") && parsed.hasMatchedOption("p")) { + main.help(); + return; + } + int returnCode = cmd.execute(args); if (returnCode != 0) { @@ -54,22 +61,40 @@ public static void main(String... args) { @Override public Integer call() throws Exception { - Plugin plugin = Plugin.of(this.pluginConfigClass) + if(forceOverwrite) { + options.put("forceOverwrite", true); + } + Plugin plugin = Plugin.of(this.pluginClass) .withSpecFile((String) options.get("specFile")) .withTargetFolder((String) options.get("targetFolder")) + .withForceOverwrite(forceOverwrite) .withOptions(options) .withChain(chain); new MainGenerator().generate(plugin); return 0; } - public void help() throws Exception { - Plugin plugin = Plugin.of(this.pluginConfigClass) - .withSpecFile((String) options.get("specFile")) - .withTargetFolder((String) options.get("targetFolder")) - .withOptions(options) - .withChain(chain); - String help = new Help().help(plugin, helpFormat); - System.out.println(help); + public void help() { + try { + Plugin plugin = Plugin.of(this.pluginClass) + .withSpecFile((String) options.get("specFile")) + .withTargetFolder((String) options.get("targetFolder")) + .withOptions(options) + .withChain(chain); + String help = new Help().help(plugin, helpFormat); + System.out.println(help); + } catch (Exception e) { + e.printStackTrace(); + } + } + + private static class HelpFormatConverter implements CommandLine.ITypeConverter { + @Override + public Help.Format convert(String value) throws Exception { + if(value == null || value.isEmpty()) { + return null; + } + return Help.Format.valueOf(value); + } } } diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Plugin.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Plugin.java index db6ee559..d8356754 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Plugin.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/Plugin.java @@ -24,6 +24,8 @@ public class Plugin { public String targetFolder; private List chain; + private boolean forceOverwrite = false; + private Map options = new HashMap<>(); private ClassLoader projectClassLoader; @@ -74,6 +76,11 @@ public Plugin withProjectClassLoader(ClassLoader projectClassLoader) { return this; } + public Plugin withForceOverwrite(boolean forceOverwrite) { + this.forceOverwrite = forceOverwrite; + return this; + } + public Plugin withOption(String name, Object value) { String lastPath = name; Map nestedTempObject = options; diff --git a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/writers/TemplateFileWriter.java b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/writers/TemplateFileWriter.java index ce946c25..51502c47 100644 --- a/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/writers/TemplateFileWriter.java +++ b/zenwave-sdk-cli/src/main/java/io/zenwave360/sdk/writers/TemplateFileWriter.java @@ -21,6 +21,8 @@ public class TemplateFileWriter implements TemplateWriter { @DocumentedOption(description = "Target folder to generate code to. If left empty, it will print to stdout.") private File targetFolder; + private boolean forceOverwrite = false; + public TemplateFileWriter withTargetFolder(File targetFolder) { this.targetFolder = targetFolder; return this; @@ -30,11 +32,15 @@ public void setTargetFolder(File targetFolder) { this.targetFolder = targetFolder; } + public void setForceOverwrite(boolean forceOverwrite) { + this.forceOverwrite = forceOverwrite; + } + @Override public void write(List templateOutputList) { templateOutputList.stream() .peek(t -> log.info("Writing template with targetFile: {}", t.getTargetFile())) - .forEach(t -> writeToFile(getFile(t.getTargetFile()), t.getContent(), t.isSkipOverwrite())); + .forEach(t -> writeToFile(getFile(t.getTargetFile()), t.getContent(), !forceOverwrite && t.isSkipOverwrite())); } protected File getFile(String fileName) { diff --git a/zenwave-sdk-cli/src/main/resources/io/zenwave360/sdk/help/list.hbs b/zenwave-sdk-cli/src/main/resources/io/zenwave360/sdk/help/list.hbs index e027eed6..cf3f4e8a 100644 --- a/zenwave-sdk-cli/src/main/resources/io/zenwave360/sdk/help/list.hbs +++ b/zenwave-sdk-cli/src/main/resources/io/zenwave360/sdk/help/list.hbs @@ -5,3 +5,5 @@ Available plugins: {{#each plugins as |plugin| ~}} {{ljust plugin.plugin.shortCode size=30 pad=" "}} {{{plugin.configClassName}}}: {{{plugin.plugin.title}}} ({{plugin.version}}) {{/each}} + +Use: "jbang zw -p -h" to get help on a specific plugin diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/HelpTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/HelpTest.java index 3af7079c..1dbf71da 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/HelpTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/HelpTest.java @@ -6,14 +6,29 @@ public class HelpTest { + @Test + public void testNoOptionsHelp() { + Main.main(); + } + @Test public void testMainHelp() { + Main.main("-h"); + } + + @Test + public void testPluginHelp() { Main.main("-h", "-p", NoOpPluginConfiguration.class.getName()); } + @Test + public void testPluginMarkdownHelp() { + Main.main("-h", "markdown", "-p", NoOpPluginConfiguration.class.getName()); + } + @Test public void testDiscoverAvailablePlugins() { - Main.main("-h", "-f", Help.Format.list.toString()); + Main.main("-h", Help.Format.list.toString()); } } diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainGeneratorTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainGeneratorTest.java index 111ba660..9092d1f3 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainGeneratorTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainGeneratorTest.java @@ -40,7 +40,8 @@ public void testGenerator() throws Exception { Plugin plugin = new Plugin() .withSpecFile("classpath:io/zenwave360/sdk/resources/asyncapi/asyncapi-circular-refs.yml") .withTargetFolder("target/zenwave630/out") - .withChain(DefaultYamlParser.class, AsyncApiProcessor.class, NoOpGenerator.class, TemplateFileWriter.class); + .withChain(DefaultYamlParser.class, AsyncApiProcessor.class, NoOpGenerator.class, TemplateFileWriter.class) + .withOption("forceOverwrite", true); new MainGenerator().generate(plugin); diff --git a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainTest.java b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainTest.java index ddf18de9..c968bfc6 100644 --- a/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainTest.java +++ b/zenwave-sdk-cli/src/test/java/io/zenwave360/sdk/MainTest.java @@ -57,6 +57,7 @@ public void testMain_with_array_options() { Main.main( "-c", StringUtils.join(processors, ","), + "--force", "specFile=classpath:io/zenwave360/sdk/resources/asyncapi/asyncapi-circular-refs.yml", "targetFolder=target/zenwave/out", "inner.specFile=target/zenwave/out",