Skip to content

Commit

Permalink
Merge pull request quarkusio#44388 from gsmet/fix-config-generation
Browse files Browse the repository at this point in the history
Fix some invalid configuration cases for doc generation and fail the build if some description are missing
  • Loading branch information
sberyozkin authored Nov 8, 2024
2 parents 7603085 + 1813c5a commit d1c3ae8
Show file tree
Hide file tree
Showing 10 changed files with 132 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
import io.quarkus.annotation.processor.documentation.config.model.Extension;
import io.quarkus.maven.config.doc.generator.Format;
import io.quarkus.maven.config.doc.generator.Formatter;
import io.quarkus.maven.config.doc.generator.GenerationReport;
import io.quarkus.maven.config.doc.generator.GenerationReport.GenerationViolation;
import io.quarkus.qute.Engine;
import io.quarkus.qute.ReflectionValueResolver;
import io.quarkus.qute.UserTagSectionHelper;
Expand Down Expand Up @@ -91,13 +93,14 @@ public void execute() throws MojoExecutionException, MojoFailureException {

List<Path> targetDirectories = findTargetDirectories(resolvedScanDirectory);

GenerationReport generationReport = new GenerationReport();
JavadocRepository javadocRepository = JavadocMerger.mergeJavadocElements(targetDirectories);
MergedModel mergedModel = ModelMerger.mergeModel(javadocRepository, targetDirectories, true);

Format normalizedFormat = Format.normalizeFormat(format);

String normalizedTheme = normalizedFormat.normalizeTheme(theme);
Formatter formatter = Formatter.getFormatter(javadocRepository, enableEnumTooltips, normalizedFormat);
Formatter formatter = Formatter.getFormatter(generationReport, javadocRepository, enableEnumTooltips, normalizedFormat);
Engine quteEngine = initializeQuteEngine(formatter, normalizedFormat, normalizedTheme);

// we generate a file per extension + top level prefix
Expand Down Expand Up @@ -168,6 +171,21 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}
}

if (!generationReport.getViolations().isEmpty()) {
StringBuilder report = new StringBuilder(
"One or more errors happened during the configuration documentation generation. Here is a full report:\n\n");
for (Entry<String, List<GenerationViolation>> violationsEntry : generationReport.getViolations().entrySet()) {
report.append("- ").append(violationsEntry.getKey()).append("\n");
for (GenerationViolation violation : violationsEntry.getValue()) {
report.append(" . ").append(violation.sourceElement()).append(" - ").append(violation.message())
.append("\n");
}
report.append("\n----\n\n");
}

throw new IllegalStateException(report.toString());
}

// we generate files for generated sections
for (Entry<Extension, List<ConfigSection>> extensionConfigSectionsEntry : mergedModel.getGeneratedConfigSections()
.entrySet()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,16 @@
import io.quarkus.annotation.processor.documentation.config.model.JavadocFormat;
import io.quarkus.annotation.processor.documentation.config.util.Types;
import io.quarkus.maven.config.doc.GenerateConfigDocMojo.Context;
import io.quarkus.maven.config.doc.generator.GenerationReport.ConfigPropertyGenerationViolation;

abstract class AbstractFormatter implements Formatter {

protected final GenerationReport generationReport;
protected final JavadocRepository javadocRepository;
protected final boolean enableEnumTooltips;

AbstractFormatter(JavadocRepository javadocRepository, boolean enableEnumTooltips) {
AbstractFormatter(GenerationReport generationReport, JavadocRepository javadocRepository, boolean enableEnumTooltips) {
this.generationReport = generationReport;
this.javadocRepository = javadocRepository;
this.enableEnumTooltips = enableEnumTooltips;
}
Expand All @@ -41,12 +44,17 @@ public String formatDescription(ConfigProperty configProperty) {
configProperty.getSourceElementName());

if (javadocElement.isEmpty()) {
generationReport.addError(new ConfigPropertyGenerationViolation(configProperty.getSourceType(),
configProperty.getSourceElementName(), configProperty.getSourceElementType(), "Missing Javadoc"));
return null;
}

String description = JavadocTransformer.transform(javadocElement.get().description(), javadocElement.get().format(),
javadocFormat());
if (description == null || description.isBlank()) {
generationReport.addError(new ConfigPropertyGenerationViolation(configProperty.getSourceType(),
configProperty.getSourceElementName(), configProperty.getSourceElementType(),
"Transformed Javadoc is empty"));
return null;
}

Expand Down Expand Up @@ -204,17 +212,20 @@ public String formatSectionTitle(ConfigSection configSection) {
configSection.getSourceElementName());

if (javadocElement.isEmpty()) {
throw new IllegalStateException(
"Couldn't find section title for: " + configSection.getSourceType() + "#"
+ configSection.getSourceElementName());
generationReport.addError(new ConfigPropertyGenerationViolation(configSection.getSourceType(),
configSection.getSourceElementName(), configSection.getSourceElementType(), "Missing Javadoc"));

return null;
}

String javadoc = JavadocTransformer.transform(javadocElement.get().description(), javadocElement.get().format(),
javadocFormat());
if (javadoc == null || javadoc.isBlank()) {
throw new IllegalStateException(
"Couldn't find section title for: " + configSection.getSourceType() + "#"
+ configSection.getSourceElementName());
generationReport.addError(new ConfigPropertyGenerationViolation(configSection.getSourceType(),
configSection.getSourceElementName(), configSection.getSourceElementType(),
"Transformed Javadoc is empty"));

return null;
}

return trimFinalDot(javadoc);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ final class AsciidocFormatter extends AbstractFormatter {
private static final Pattern ANGLE_BRACKETS_WITH_DESCRIPTION_PATTERN = Pattern.compile("<<([a-z0-9_\\-#\\.]+?),([^>]+?)>>",
Pattern.CASE_INSENSITIVE);

AsciidocFormatter(JavadocRepository javadocRepository, boolean enableEnumTooltips) {
super(javadocRepository, enableEnumTooltips);
AsciidocFormatter(GenerationReport generationReport, JavadocRepository javadocRepository, boolean enableEnumTooltips) {
super(generationReport, javadocRepository, enableEnumTooltips);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,13 @@ default String formatDescription(ConfigProperty configProperty, Extension extens

String formatName(Extension extension);

static Formatter getFormatter(JavadocRepository javadocRepository, boolean enableEnumTooltips, Format format) {
static Formatter getFormatter(GenerationReport generationReport, JavadocRepository javadocRepository,
boolean enableEnumTooltips, Format format) {
switch (format) {
case asciidoc:
return new AsciidocFormatter(javadocRepository, enableEnumTooltips);
return new AsciidocFormatter(generationReport, javadocRepository, enableEnumTooltips);
case markdown:
return new MarkdownFormatter(javadocRepository);
return new MarkdownFormatter(generationReport, javadocRepository);
default:
throw new IllegalArgumentException("Unsupported format: " + format);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.quarkus.maven.config.doc.generator;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import io.quarkus.annotation.processor.documentation.config.model.SourceElementType;

public class GenerationReport {

private Map<String, List<GenerationViolation>> violations = new LinkedHashMap<>();

void addError(GenerationViolation error) {
this.violations.computeIfAbsent(error.sourceType(), k -> new ArrayList<>()).add(error);
}

public Map<String, List<GenerationViolation>> getViolations() {
return violations;
}

public record ConfigPropertyGenerationViolation(String sourceType, String sourceElement,
SourceElementType sourceElementType, String message) implements GenerationViolation {

@Override
public String sourceElement() {
return sourceElement + (sourceElementType == SourceElementType.METHOD ? "()" : "");
}
}

public interface GenerationViolation {

String sourceType();

String sourceElement();

String message();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ final class MarkdownFormatter extends AbstractFormatter {

private static final String MORE_INFO_ABOUT_TYPE_FORMAT = "[🛈](#%s)";

MarkdownFormatter(JavadocRepository javadocRepository) {
super(javadocRepository, false);
MarkdownFormatter(GenerationReport generationReport, JavadocRepository javadocRepository) {
super(generationReport, javadocRepository, false);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigGroup;

@ConfigGroup
public interface CommonConfig {
/**
* Path to the JVM Dockerfile.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,47 +72,47 @@ public final class TransactionManagerConfiguration {
*/
@ConfigItem
public ObjectStoreConfig objectStore;
}

@ConfigGroup
class ObjectStoreConfig {
/**
* The name of the directory where the transaction logs will be stored when using the {@code file-system} object store.
* If the value is not absolute then the directory is relative
* to the <em>user.dir</em> system property.
*/
@ConfigItem(defaultValue = "ObjectStore")
public String directory;

/**
* The type of object store.
*/
@ConfigItem(defaultValue = "file-system")
public ObjectStoreType type;

/**
* The name of the datasource where the transaction logs will be stored when using the {@code jdbc} object store.
* <p>
* If undefined, it will use the default datasource.
*/
@ConfigItem
public Optional<String> datasource = Optional.empty();

/**
* Whether to create the table if it does not exist.
*/
@ConfigItem(defaultValue = "false")
public boolean createTable;

/**
* Whether to drop the table on startup.
*/
@ConfigItem(defaultValue = "false")
public boolean dropTable;

/**
* The prefix to apply to the table.
*/
@ConfigItem(defaultValue = "quarkus_")
public String tablePrefix;
@ConfigGroup
public static class ObjectStoreConfig {
/**
* The name of the directory where the transaction logs will be stored when using the {@code file-system} object store.
* If the value is not absolute then the directory is relative
* to the <em>user.dir</em> system property.
*/
@ConfigItem(defaultValue = "ObjectStore")
public String directory;

/**
* The type of object store.
*/
@ConfigItem(defaultValue = "file-system")
public ObjectStoreType type;

/**
* The name of the datasource where the transaction logs will be stored when using the {@code jdbc} object store.
* <p>
* If undefined, it will use the default datasource.
*/
@ConfigItem
public Optional<String> datasource = Optional.empty();

/**
* Whether to create the table if it does not exist.
*/
@ConfigItem(defaultValue = "false")
public boolean createTable;

/**
* Whether to drop the table on startup.
*/
@ConfigItem(defaultValue = "false")
public boolean dropTable;

/**
* The prefix to apply to the table.
*/
@ConfigItem(defaultValue = "quarkus_")
public String tablePrefix;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@
import java.util.Optional;

import io.quarkus.runtime.annotations.ConfigDocMapKey;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithDefault;

@ConfigGroup
public interface OidcClientCommonConfig extends OidcCommonConfig {
/**
* The OIDC token endpoint that issues access and refresh tokens;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@
import java.util.OptionalInt;

import io.quarkus.runtime.annotations.ConfigDocDefault;
import io.quarkus.runtime.annotations.ConfigGroup;
import io.smallrye.config.WithDefault;

@ConfigGroup
public interface OidcCommonConfig {
/**
* The base URL of the OpenID Connect (OIDC) server, for example, `https://host:port/auth`.
Expand Down

0 comments on commit d1c3ae8

Please sign in to comment.