mirror of
https://github.com/OpenAPITools/openapi-generator.git
synced 2025-12-09 23:56:09 +00:00
[cli] Full config help details (#4928)
* [cli] Dump additional generator info via config-help (plain text) * [cli] Dump additional generator info via config-help (markdown)
This commit is contained in:
@@ -30,19 +30,21 @@ import org.slf4j.LoggerFactory;
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.apache.commons.lang3.StringEscapeUtils.escapeHtml4;
|
||||
import static org.apache.commons.lang3.StringUtils.isEmpty;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
@Command(name = "config-help", description = "Config help for chosen lang")
|
||||
public class ConfigHelp implements Runnable {
|
||||
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(Generate.class);
|
||||
|
||||
public static final String FORMAT_TEXT = "text";
|
||||
public static final String FORMAT_MARKDOWN = "markdown";
|
||||
public static final String FORMAT_YAMLSAMPLE = "yamlsample";
|
||||
private static final String FORMAT_TEXT = "text";
|
||||
private static final String FORMAT_MARKDOWN = "markdown";
|
||||
private static final String FORMAT_YAMLSAMPLE = "yamlsample";
|
||||
|
||||
@Option(name = {"-g",
|
||||
"--generator-name"}, title = "generator name", description = "generator to get config help for")
|
||||
@@ -61,18 +63,41 @@ public class ConfigHelp implements Runnable {
|
||||
FORMAT_TEXT, FORMAT_MARKDOWN, FORMAT_YAMLSAMPLE})
|
||||
private String format;
|
||||
|
||||
@Option(name = {"--import-mappings"}, title = "import mappings", description = "displays the default import mappings (types and aliases, and what imports they will pull into the template)")
|
||||
private Boolean importMappings;
|
||||
|
||||
@Option(name = {"--language-specific-primitive"}, title = "language specific primitives", description = "displays the language specific primitives (types which require no additional imports, or which may conflict with user defined model names)")
|
||||
private Boolean languageSpecificPrimitives;
|
||||
|
||||
@Option(name = {"--reserved-words"}, title = "language specific reserved words", description = "displays the reserved words which may result in renamed model or property names")
|
||||
private Boolean reservedWords;
|
||||
|
||||
@Option(name = {"--instantiation-types"}, title = "instantiation types", description = "displays types used to instantiate simple type/alias names")
|
||||
private Boolean instantiationTypes;
|
||||
|
||||
@Option(name = {
|
||||
"--markdown-header"}, title = "markdown header", description = "When format=markdown, include this option to write out markdown headers (e.g. for docusaurus).")
|
||||
private Boolean markdownHeader;
|
||||
|
||||
@Option(name = {"--full-details"}, title = "full generator details", description = "displays CLI options as well as other configs/mappings (implies --instantiation-types, --reserved-words, --language-specific-primitives, --import-mappings, --supporting-files)")
|
||||
private Boolean fullDetails;
|
||||
|
||||
private String newline = System.lineSeparator();
|
||||
|
||||
@Override public void run() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (isEmpty(generatorName)) {
|
||||
LOGGER.error("[error] A generator name (--generator-name / -g) is required.");
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(fullDetails)) {
|
||||
instantiationTypes = Boolean.TRUE;
|
||||
reservedWords = Boolean.TRUE;
|
||||
languageSpecificPrimitives = Boolean.TRUE;
|
||||
importMappings = Boolean.TRUE;
|
||||
}
|
||||
|
||||
try {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
CodegenConfig config = CodegenConfigLoader.forName(generatorName);
|
||||
@@ -97,9 +122,9 @@ public class ConfigHelp implements Runnable {
|
||||
|
||||
if (!isEmpty(outputFile)) {
|
||||
File out = Paths.get(outputFile).toFile();
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
File parentFolder = out.getParentFile();
|
||||
if (parentFolder != null && parentFolder.isDirectory()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
parentFolder.mkdirs();
|
||||
}
|
||||
|
||||
@@ -119,34 +144,6 @@ public class ConfigHelp implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private void generateYamlSample(StringBuilder sb, CodegenConfig config) {
|
||||
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
|
||||
sb.append("# Description: ").append(langCliOption.getDescription()).append(newline);
|
||||
|
||||
Map<String, String> enums = langCliOption.getEnum();
|
||||
if (enums != null) {
|
||||
sb.append("# Available Values:").append(newline);
|
||||
|
||||
for (Map.Entry<String, String> entry : enums.entrySet()) {
|
||||
sb.append("# ").append(entry.getKey()).append(newline);
|
||||
sb.append("# ").append(entry.getValue()).append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
String defaultValue = langCliOption.getDefault();
|
||||
|
||||
if (defaultValue != null) {
|
||||
sb.append(langCliOption.getOpt()).append(": ").append(defaultValue).append(newline);
|
||||
} else {
|
||||
sb.append("# ").append(langCliOption.getOpt()).append(": ").append(newline);
|
||||
}
|
||||
|
||||
sb.append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateMarkdownHelp(StringBuilder sb, CodegenConfig config) {
|
||||
if (Boolean.TRUE.equals(markdownHeader)) {
|
||||
sb.append("---").append(newline);
|
||||
@@ -197,6 +194,91 @@ public class ConfigHelp implements Runnable {
|
||||
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
|
||||
if (Boolean.TRUE.equals(importMappings)) {
|
||||
sb.append(newline);
|
||||
sb.append("## IMPORT MAPPING");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
|
||||
sb.append("| Type/Alias | Imports |").append(newline);
|
||||
sb.append("| ---------- | ------- |").append(newline);
|
||||
|
||||
config.importMapping().forEach((key, value)-> {
|
||||
sb.append("|").append(escapeHtml4(key)).append("|").append(escapeHtml4(value)).append("|");
|
||||
sb.append(newline);
|
||||
});
|
||||
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(instantiationTypes)) {
|
||||
sb.append(newline);
|
||||
sb.append("## INSTANTIATION TYPES");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
|
||||
sb.append("| Type/Alias | Instantiated By |").append(newline);
|
||||
sb.append("| ---------- | --------------- |").append(newline);
|
||||
|
||||
config.instantiationTypes().forEach((key, value)-> {
|
||||
sb.append("|").append(escapeHtml4(key)).append("|").append(escapeHtml4(value)).append("|");
|
||||
sb.append(newline);
|
||||
});
|
||||
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(languageSpecificPrimitives)) {
|
||||
sb.append(newline);
|
||||
sb.append("## LANGUAGE PRIMITIVES");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
|
||||
config.languageSpecificPrimitives().forEach(s -> sb.append("<li>").append(escapeHtml4(s)).append("</li>").append(newline));
|
||||
sb.append("</ul>");
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(reservedWords)) {
|
||||
sb.append(newline);
|
||||
sb.append("## RESERVED WORDS");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
sb.append("<ul data-columns=\"2\" style=\"list-style-type: disc;-webkit-columns:2;-moz-columns:2;columns:2;-moz-column-fill:auto;column-fill:auto\">");
|
||||
config.reservedWords().forEach(s -> sb.append("<li>").append(escapeHtml4(s)).append("</li>").append(newline));
|
||||
sb.append("</ul>");
|
||||
sb.append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateYamlSample(StringBuilder sb, CodegenConfig config) {
|
||||
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
|
||||
sb.append("# Description: ").append(langCliOption.getDescription()).append(newline);
|
||||
|
||||
Map<String, String> enums = langCliOption.getEnum();
|
||||
if (enums != null) {
|
||||
sb.append("# Available Values:").append(newline);
|
||||
|
||||
for (Map.Entry<String, String> entry : enums.entrySet()) {
|
||||
sb.append("# ").append(entry.getKey()).append(newline);
|
||||
sb.append("# ").append(entry.getValue()).append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
String defaultValue = langCliOption.getDefault();
|
||||
|
||||
if (defaultValue != null) {
|
||||
sb.append(langCliOption.getOpt()).append(": ").append(defaultValue).append(newline);
|
||||
} else {
|
||||
sb.append("# ").append(langCliOption.getOpt()).append(": ").append(newline);
|
||||
}
|
||||
|
||||
sb.append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
private void generatePlainTextHelp(StringBuilder sb, CodegenConfig config) {
|
||||
@@ -207,14 +289,112 @@ public class ConfigHelp implements Runnable {
|
||||
}
|
||||
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
|
||||
String optIndent = "\t";
|
||||
String optNestedIndent = "\t ";
|
||||
|
||||
for (CliOption langCliOption : config.cliOptions()) {
|
||||
sb.append("\t").append(langCliOption.getOpt());
|
||||
sb.append(optIndent).append(langCliOption.getOpt());
|
||||
sb.append(newline);
|
||||
sb.append("\t ").append(langCliOption.getOptionHelp()
|
||||
.replaceAll("\n", System.lineSeparator() + "\t "));
|
||||
sb.append(optNestedIndent).append(langCliOption.getOptionHelp()
|
||||
.replaceAll("\n", System.lineSeparator() + optNestedIndent));
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(importMappings)) {
|
||||
sb.append(newline);
|
||||
sb.append("IMPORT MAPPING");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
Map<String, String> map = config.importMapping();
|
||||
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Type/Alias", "Imports");
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(instantiationTypes)) {
|
||||
sb.append(newline);
|
||||
sb.append("INSTANTIATION TYPES");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
Map<String, String> map = config.instantiationTypes();
|
||||
writePlainTextFromMap(sb, map, optIndent, optNestedIndent, "Type/Alias", "Instantiated By");
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(languageSpecificPrimitives)) {
|
||||
sb.append(newline);
|
||||
sb.append("LANGUAGE PRIMITIVES");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
String[] arr = config.languageSpecificPrimitives().stream().sorted().toArray(String[]::new);
|
||||
writePlainTextFromArray(sb, arr, optIndent);
|
||||
sb.append(newline);
|
||||
}
|
||||
|
||||
if (Boolean.TRUE.equals(reservedWords)) {
|
||||
sb.append(newline);
|
||||
sb.append("RESERVED WORDS");
|
||||
sb.append(newline);
|
||||
sb.append(newline);
|
||||
String[] arr = config.reservedWords().stream().sorted().toArray(String[]::new);
|
||||
writePlainTextFromArray(sb, arr, optIndent);
|
||||
sb.append(newline);
|
||||
}
|
||||
}
|
||||
|
||||
private void writePlainTextFromMap(
|
||||
StringBuilder sb,
|
||||
Map<String, String> map,
|
||||
String optIndent,
|
||||
String optNestedIndent,
|
||||
@SuppressWarnings("SameParameterValue") String keyHeader,
|
||||
String valueHeader) {
|
||||
if (map != null && map.size() > 0) {
|
||||
int maxKey = keyHeader.length();
|
||||
int maxValue = valueHeader.length();
|
||||
|
||||
for (Map.Entry<String, String> entry : map.entrySet()) {
|
||||
String k = entry.getKey();
|
||||
String v = entry.getValue();
|
||||
maxKey = Math.max(maxKey, k.length());
|
||||
maxValue = Math.max(maxValue, v.length());
|
||||
}
|
||||
|
||||
String format = "%-" + maxKey + "s\t%-" + maxValue + "s";
|
||||
sb.append(optIndent).append(String.format(Locale.ROOT, format, keyHeader, valueHeader));
|
||||
sb.append(newline);
|
||||
sb.append(optIndent).append(String.format(Locale.ROOT, format, StringUtils.repeat("-", maxKey), StringUtils.repeat("-", maxValue)));
|
||||
map.forEach((key, value) -> {
|
||||
sb.append(newline);
|
||||
sb.append(optIndent).append(String.format(Locale.ROOT, format, key, value));
|
||||
});
|
||||
} else {
|
||||
sb.append(optIndent).append("None");
|
||||
}
|
||||
}
|
||||
|
||||
private void writePlainTextFromArray(StringBuilder sb, String[] arr, String optIndent) {
|
||||
if (arr.length > 0) {
|
||||
// target a width of 20, then take the max up to 40.
|
||||
int width = 20;
|
||||
for (String s : arr) {
|
||||
width = Math.max(width, Math.min(40, s.length()));
|
||||
}
|
||||
|
||||
// do three columns if possible (assume terminal width ~90), otherwise do two columns.
|
||||
int columns = width < 30 ? 3 : 2;
|
||||
String format = "%-" + (90 / columns) + "s";
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
String current = arr[i];
|
||||
sb.append(optIndent).append(String.format(Locale.ROOT, format, current));
|
||||
if (i % columns == 0) {
|
||||
sb.append(newline);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sb.append(optIndent).append("None");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user