Avoid nested table for downstream docs (#17145)

* Avoid nested table for downstream docs

CIAM-5051

* WIP

* Next iteration: making the options and their values monospaced. Merge the default column into the values column

---------

Co-authored-by: Stian Thorgersen <stianst@gmail.com>
This commit is contained in:
Alexander Schwartz 2023-02-21 14:44:39 +01:00 committed by GitHub
parent 1ed46ac56b
commit 9ebbf9ceef
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 21 deletions

View file

@ -5,33 +5,29 @@
</#macro> </#macro>
<#macro list options buildIcon=true> <#macro list options buildIcon=true>
<#if buildIcon> [cols="12a,4",role="options"]
[cols="12a,4,4,1",role="options"]
|=== |===
| |Type|Default| | |Value
<#else>
[cols="12a,4,4",role="options"]
|===
| |Type|Default
</#if>
<#list options as option> <#list options as option>
| |
[.options-key]#${option.key}# [.options-key]#``${option.key}``# <#if buildIcon><#if option.build>[.none]#icon:tools[role=options-build]#</#if></#if>
[.options-description]#${option.description}# [.options-description]#${option.description}#
[#option-extended-${option.key},role="options-extended"] [#option-extended-${option.key},role="options-extended"]
!=== --
!<#if option.descriptionExtended?has_content>[.options-description-extended]#${option.descriptionExtended!}#</#if> <#if option.descriptionExtended?has_content>[.options-description-extended]#${option.descriptionExtended!}#</#if>
![.options-description-example]#*CLI:* `${option.keyCli}`#
![.options-description-example]#*Env:* `${option.keyEnv}`#
!===
|<#if option.expectedValues?has_content>[.options-type]#${option.expectedValues?join(", ")}#</#if>
|<#if option.defaultValue?has_content>[.options-default]#${option.defaultValue!}#</#if> *CLI:* `${option.keyCli}` +
*Env:* `${option.keyEnv}`
--
|<#if option.expectedValues?has_content>
<#list option.expectedValues as value>`+${value!}+`<#if option.defaultValue?has_content && value = option.defaultValue> (default)</#if><#if value?has_next>, </#if></#list>
<#else>
<#if option.defaultValue?has_content>[.options-default]#`+${option.defaultValue!}+`# (default)</#if><#if option.type?has_content && option.defaultValue?has_content> or </#if><#if option.type?has_content && !option.expectedValues?has_content>any `+${option.type!}+`</#if>
</#if>
<#if buildIcon>|<#if option.build>icon:tools[role=options-build]</#if></#if>
</#list> </#list>
|=== |===

View file

@ -14,6 +14,7 @@ import org.keycloak.quarkus.runtime.Providers;
import org.keycloak.quarkus.runtime.configuration.Configuration; import org.keycloak.quarkus.runtime.configuration.Configuration;
import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers; import org.keycloak.quarkus.runtime.configuration.mappers.PropertyMappers;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -33,11 +34,15 @@ public class Options {
options = PropertyMappers.getMappers().stream() options = PropertyMappers.getMappers().stream()
.filter(m -> !m.isHidden()) .filter(m -> !m.isHidden())
.filter(propertyMapper -> Objects.nonNull(propertyMapper.getDescription())) .filter(propertyMapper -> Objects.nonNull(propertyMapper.getDescription()))
.map(m -> new Option(m.getFrom(), m.getCategory(), m.isBuildTime(), m.getDescription(), (String) m.getDefaultValue().map(Object::toString).orElse(null), m.getExpectedValues())) .map(m -> new Option(m.getFrom(), m.getCategory(), m.isBuildTime(), null, m.getDescription(), (String) m.getDefaultValue().map(Object::toString).orElse(null), m.getExpectedValues()))
.sorted(Comparator.comparing(Option::getKey)) .sorted(Comparator.comparing(Option::getKey))
.collect(Collectors.toMap(Option::getKey, o -> o, (o1, o2) -> o1, LinkedHashMap::new)); // Need to ignore duplicate keys?? .collect(Collectors.toMap(Option::getKey, o -> o, (o1, o2) -> o1, LinkedHashMap::new)); // Need to ignore duplicate keys??
ProviderManager providerManager = Providers.getProviderManager(Thread.currentThread().getContextClassLoader()); ProviderManager providerManager = Providers.getProviderManager(Thread.currentThread().getContextClassLoader());
options.forEach((s, option) -> {
option.description = option.description.replaceAll("'([^ ]*)'", "`$1`");
});
for (Spi loadSpi : providerManager.loadSpis().stream().sorted(Comparator.comparing(Spi::getName)).collect(Collectors.toList())) { for (Spi loadSpi : providerManager.loadSpis().stream().sorted(Comparator.comparing(Spi::getName)).collect(Collectors.toList())) {
for (ProviderFactory providerFactory : providerManager.load(loadSpi).stream().sorted(Comparator.comparing(ProviderFactory::getId)).collect(Collectors.toList())) { for (ProviderFactory providerFactory : providerManager.load(loadSpi).stream().sorted(Comparator.comparing(ProviderFactory::getId)).collect(Collectors.toList())) {
List<ProviderConfigProperty> configMetadata = providerFactory.getConfigMetadata(); List<ProviderConfigProperty> configMetadata = providerFactory.getConfigMetadata();
@ -49,11 +54,22 @@ public class Options {
String optionPrefix = NS_KEYCLOAK_PREFIX + String.join(OPTION_PART_SEPARATOR, ArrayUtils.insert(0, new String[] {loadSpi.getName(), providerFactory.getId()}, "spi")); String optionPrefix = NS_KEYCLOAK_PREFIX + String.join(OPTION_PART_SEPARATOR, ArrayUtils.insert(0, new String[] {loadSpi.getName(), providerFactory.getId()}, "spi"));
List<Option> options = configMetadata.stream() List<Option> options = configMetadata.stream()
.map(m -> new Option(Configuration.toDashCase(optionPrefix.concat("-") + m.getName()), OptionCategory.GENERAL, false, .map(m -> new Option(Configuration.toDashCase(optionPrefix.concat("-") + m.getName()), OptionCategory.GENERAL, false,
m.getType(),
m.getHelpText(), m.getHelpText(),
m.getDefaultValue() == null ? "none" : m.getDefaultValue().toString(), m.getDefaultValue() == null ? null : m.getDefaultValue().toString(),
m.getOptions() == null ? (m.getType() == null ? Collections.emptyList() : Collections.singletonList(m.getType())) : m.getOptions())) m.getOptions() == null ? Collections.emptyList() : m.getOptions()))
.sorted(Comparator.comparing(Option::getKey)).collect(Collectors.toList()); .sorted(Comparator.comparing(Option::getKey)).collect(Collectors.toList());
ArrayList<String> booleanValues = new ArrayList<>();
booleanValues.add("true");
booleanValues.add("false");
options.forEach(option -> {
if (option.type.equals("boolean")) {
option.expectedValues = booleanValues;
}
option.description = option.description.replaceAll("'([^ ]*)'", "`$1`");
});
if (!options.isEmpty()) { if (!options.isEmpty()) {
providerOptions.computeIfAbsent(toDashCase(loadSpi.getName()), k -> new LinkedHashMap<>()).put(toDashCase(providerFactory.getId()), options); providerOptions.computeIfAbsent(toDashCase(loadSpi.getName()), k -> new LinkedHashMap<>()).put(toDashCase(providerFactory.getId()), options);
} }
@ -91,14 +107,16 @@ public class Options {
private String key; private String key;
private OptionCategory category; private OptionCategory category;
private boolean build; private boolean build;
private String type;
private String description; private String description;
private String defaultValue; private String defaultValue;
private List<String> expectedValues; private List<String> expectedValues;
public Option(String key, OptionCategory category, boolean build, String description, String defaultValue, Iterable<String> expectedValues) { public Option(String key, OptionCategory category, boolean build, String type, String description, String defaultValue, Iterable<String> expectedValues) {
this.key = key; this.key = key;
this.category = category; this.category = category;
this.build = build; this.build = build;
this.type = type;
this.description = description; this.description = description;
this.defaultValue = defaultValue; this.defaultValue = defaultValue;
this.expectedValues = StreamSupport.stream(expectedValues.spliterator(), false).collect(Collectors.toList()); this.expectedValues = StreamSupport.stream(expectedValues.spliterator(), false).collect(Collectors.toList());
@ -112,6 +130,10 @@ public class Options {
return key.substring(3); return key.substring(3);
} }
public String getType() {
return type;
}
public String getKeyCli() { public String getKeyCli() {
return "--" + key.substring(3).replace('.', '-'); return "--" + key.substring(3).replace('.', '-');
} }