mirror of
https://github.com/spring-projects/spring-boot.git
synced 2024-07-05 00:56:58 +08:00
Prepare buildSrc for migration to Antora
Replace `AsciidoctorConventions` with `AntoraConventions` in preparation for the migration to Antora. See gh-33766
This commit is contained in:
parent
d18f60e9af
commit
8d64e99714
@ -17,7 +17,7 @@ def versions = [:]
|
|||||||
new File(projectDir.parentFile, "gradle.properties").withInputStream {
|
new File(projectDir.parentFile, "gradle.properties").withInputStream {
|
||||||
def properties = new Properties()
|
def properties = new Properties()
|
||||||
properties.load(it)
|
properties.load(it)
|
||||||
["assertj", "commonsCodec", "hamcrest", "junitJupiter", "kotlin", "maven"].each {
|
["assertj", "commonsCodec", "hamcrest", "junitJupiter", "kotlin", "maven", "snakeYaml"].each {
|
||||||
versions[it] = properties[it + "Version"]
|
versions[it] = properties[it + "Version"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -42,20 +42,23 @@ dependencies {
|
|||||||
implementation(platform("org.springframework:spring-framework-bom:${versions.springFramework}"))
|
implementation(platform("org.springframework:spring-framework-bom:${versions.springFramework}"))
|
||||||
implementation("com.diffplug.gradle:goomph:3.37.2")
|
implementation("com.diffplug.gradle:goomph:3.37.2")
|
||||||
implementation("com.fasterxml.jackson.core:jackson-databind:${versions.jackson}")
|
implementation("com.fasterxml.jackson.core:jackson-databind:${versions.jackson}")
|
||||||
|
implementation("com.github.node-gradle:gradle-node-plugin:3.5.1")
|
||||||
implementation("com.gradle:gradle-enterprise-gradle-plugin:3.12.1")
|
implementation("com.gradle:gradle-enterprise-gradle-plugin:3.12.1")
|
||||||
implementation("com.tngtech.archunit:archunit:1.0.0")
|
implementation("com.tngtech.archunit:archunit:1.0.0")
|
||||||
implementation("commons-codec:commons-codec:${versions.commonsCodec}")
|
implementation("commons-codec:commons-codec:${versions.commonsCodec}")
|
||||||
implementation("de.undercouch.download:de.undercouch.download.gradle.plugin:5.5.0")
|
implementation("de.undercouch.download:de.undercouch.download.gradle.plugin:5.5.0")
|
||||||
|
implementation("io.spring.gradle.antora:spring-antora-plugin:0.0.1")
|
||||||
implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}")
|
implementation("io.spring.javaformat:spring-javaformat-gradle-plugin:${javaFormatVersion}")
|
||||||
|
implementation("io.spring.nohttp:nohttp-gradle:0.0.11")
|
||||||
implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1")
|
implementation("org.apache.httpcomponents.client5:httpclient5:5.3.1")
|
||||||
implementation("org.apache.maven:maven-embedder:${versions.maven}")
|
implementation("org.apache.maven:maven-embedder:${versions.maven}")
|
||||||
implementation("org.asciidoctor:asciidoctor-gradle-jvm:3.3.2")
|
implementation("org.antora:gradle-antora-plugin:1.0.0")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}")
|
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${versions.kotlin}")
|
implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${versions.kotlin}")
|
||||||
implementation("org.springframework:spring-context")
|
implementation("org.springframework:spring-context")
|
||||||
implementation("org.springframework:spring-core")
|
implementation("org.springframework:spring-core")
|
||||||
implementation("org.springframework:spring-web")
|
implementation("org.springframework:spring-web")
|
||||||
implementation("io.spring.nohttp:nohttp-gradle:0.0.11")
|
implementation("org.yaml:snakeyaml:${versions.snakeYaml}")
|
||||||
|
|
||||||
testImplementation("org.assertj:assertj-core:${versions.assertj}")
|
testImplementation("org.assertj:assertj-core:${versions.assertj}")
|
||||||
testImplementation("org.hamcrest:hamcrest:${versions.hamcrest}")
|
testImplementation("org.hamcrest:hamcrest:${versions.hamcrest}")
|
||||||
|
@ -0,0 +1,155 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2023-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.github.gradle.node.NodeExtension;
|
||||||
|
import io.spring.gradle.antora.GenerateAntoraYmlPlugin;
|
||||||
|
import io.spring.gradle.antora.GenerateAntoraYmlTask;
|
||||||
|
import org.antora.gradle.AntoraExtension;
|
||||||
|
import org.antora.gradle.AntoraPlugin;
|
||||||
|
import org.antora.gradle.AntoraTask;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.file.RegularFile;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.logging.LogLevel;
|
||||||
|
import org.gradle.api.plugins.JavaBasePlugin;
|
||||||
|
import org.gradle.api.provider.Provider;
|
||||||
|
import org.gradle.api.tasks.TaskContainer;
|
||||||
|
|
||||||
|
import org.springframework.boot.build.antora.AntoraAsciidocAttributes;
|
||||||
|
import org.springframework.boot.build.antora.Extensions;
|
||||||
|
import org.springframework.boot.build.antora.GenerateAntoraPlaybook;
|
||||||
|
import org.springframework.boot.build.bom.BomExtension;
|
||||||
|
import org.springframework.boot.build.constraints.ExtractVersionConstraints;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Conventions that are applied in the presence of the {@link AntoraPlugin} and
|
||||||
|
* {@link GenerateAntoraYmlPlugin}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class AntoraConventions {
|
||||||
|
|
||||||
|
private static final String DEPENDENCIES_PATH = ":spring-boot-project:spring-boot-dependencies";
|
||||||
|
|
||||||
|
private static final String ANTORA_VERSION = "3.2.0-alpha.4";
|
||||||
|
|
||||||
|
private static final String ANTORA_SOURCE_DIR = "src/docs/antora";
|
||||||
|
|
||||||
|
private static final List<String> NAV_FILES = List.of("nav.adoc", "local-nav.adoc");
|
||||||
|
|
||||||
|
void apply(Project project) {
|
||||||
|
project.getPlugins().withType(AntoraPlugin.class, (antoraPlugin) -> apply(project, antoraPlugin));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void apply(Project project, AntoraPlugin antoraPlugin) {
|
||||||
|
ExtractVersionConstraints dependencyVersionsTask = addDependencyVersionsTask(project);
|
||||||
|
project.getPlugins().apply(GenerateAntoraYmlPlugin.class);
|
||||||
|
TaskContainer tasks = project.getTasks();
|
||||||
|
GenerateAntoraPlaybook generateAntoraPlaybookTask = tasks.create("generateAntoraPlaybook",
|
||||||
|
GenerateAntoraPlaybook.class);
|
||||||
|
tasks.withType(GenerateAntoraYmlTask.class, (generateAntoraYmlTask) -> configureGenerateAntoraYmlTask(project,
|
||||||
|
generateAntoraYmlTask, dependencyVersionsTask));
|
||||||
|
tasks.withType(AntoraTask.class,
|
||||||
|
(antoraTask) -> configureAntoraTask(project, antoraTask, generateAntoraPlaybookTask));
|
||||||
|
project.getExtensions().configure(AntoraExtension.class, (antoraExtension) -> {
|
||||||
|
RegularFileProperty outputFile = generateAntoraPlaybookTask.getOutputFile();
|
||||||
|
configureAntoraExtension(project, antoraExtension, outputFile);
|
||||||
|
});
|
||||||
|
project.getExtensions()
|
||||||
|
.configure(NodeExtension.class, (nodeExtension) -> configureNodeExtension(project, nodeExtension));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExtractVersionConstraints addDependencyVersionsTask(Project project) {
|
||||||
|
return project.getTasks()
|
||||||
|
.create("dependencyVersions", ExtractVersionConstraints.class,
|
||||||
|
(task) -> task.enforcedPlatform(DEPENDENCIES_PATH));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureGenerateAntoraYmlTask(Project project, GenerateAntoraYmlTask generateAntoraYmlTask,
|
||||||
|
ExtractVersionConstraints dependencyVersionsTask) {
|
||||||
|
generateAntoraYmlTask.getOutputs().doNotCacheIf("getAsciidocAttributes() changes output", (task) -> true);
|
||||||
|
generateAntoraYmlTask.dependsOn(dependencyVersionsTask);
|
||||||
|
generateAntoraYmlTask.setProperty("componentName", "spring-boot");
|
||||||
|
generateAntoraYmlTask.setProperty("outputFile",
|
||||||
|
new File(project.getBuildDir(), "generated/docs/antora-yml/antora.yml"));
|
||||||
|
generateAntoraYmlTask.setProperty("yml", getDefaultYml(project));
|
||||||
|
generateAntoraYmlTask.doFirst((task) -> generateAntoraYmlTask.getAsciidocAttributes()
|
||||||
|
.putAll(project.provider(() -> getAsciidocAttributes(project, dependencyVersionsTask))));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, ?> getDefaultYml(Project project) {
|
||||||
|
String navFile = null;
|
||||||
|
for (String candidate : NAV_FILES) {
|
||||||
|
if (project.file(ANTORA_SOURCE_DIR + "/" + candidate).exists()) {
|
||||||
|
Assert.state(navFile == null, "Multiple nav files found");
|
||||||
|
navFile = candidate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Map<String, Object> defaultYml = new LinkedHashMap<>();
|
||||||
|
defaultYml.put("title", "Spring Boot");
|
||||||
|
if (navFile != null) {
|
||||||
|
defaultYml.put("nav", List.of(navFile));
|
||||||
|
}
|
||||||
|
return defaultYml;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getAsciidocAttributes(Project project,
|
||||||
|
ExtractVersionConstraints dependencyVersionsTask) {
|
||||||
|
BomExtension bom = (BomExtension) project.project(DEPENDENCIES_PATH).getExtensions().getByName("bom");
|
||||||
|
Map<String, String> dependencyVersions = dependencyVersionsTask.getVersionConstraints();
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes(project, bom, dependencyVersions);
|
||||||
|
return attributes.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureAntoraTask(Project project, AntoraTask antoraTask,
|
||||||
|
GenerateAntoraPlaybook generateAntoraPlaybookTask) {
|
||||||
|
antoraTask.setGroup("Documentation");
|
||||||
|
antoraTask.getDependsOn().add(generateAntoraPlaybookTask);
|
||||||
|
project.getPlugins()
|
||||||
|
.withType(JavaBasePlugin.class,
|
||||||
|
(javaBasePlugin) -> project.getTasks()
|
||||||
|
.getByName(JavaBasePlugin.CHECK_TASK_NAME)
|
||||||
|
.dependsOn(antoraTask));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureAntoraExtension(Project project, AntoraExtension antoraExtension,
|
||||||
|
Provider<RegularFile> playbook) {
|
||||||
|
antoraExtension.getVersion().convention(ANTORA_VERSION);
|
||||||
|
antoraExtension.getPackages().convention(Extensions.packages());
|
||||||
|
antoraExtension.getPlaybook().convention(playbook.map(RegularFile::getAsFile));
|
||||||
|
if (project.getGradle().getStartParameter().getLogLevel() != LogLevel.DEBUG) {
|
||||||
|
antoraExtension.getOptions().add("--quiet");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
antoraExtension.getOptions().addAll("--log-level", "all");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void configureNodeExtension(Project project, NodeExtension nodeExtension) {
|
||||||
|
File buildDir = project.getBuildDir();
|
||||||
|
nodeExtension.getWorkDir().set(buildDir.toPath().resolve(".gradle/nodejs").toFile());
|
||||||
|
nodeExtension.getNpmWorkDir().set(buildDir.toPath().resolve(".gradle/npm").toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,159 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2012-2024 the original author or authors.
|
|
||||||
*
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* https://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.springframework.boot.build;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import org.asciidoctor.gradle.jvm.AbstractAsciidoctorTask;
|
|
||||||
import org.asciidoctor.gradle.jvm.AsciidoctorJExtension;
|
|
||||||
import org.asciidoctor.gradle.jvm.AsciidoctorJPlugin;
|
|
||||||
import org.asciidoctor.gradle.jvm.AsciidoctorTask;
|
|
||||||
import org.gradle.api.JavaVersion;
|
|
||||||
import org.gradle.api.Project;
|
|
||||||
import org.gradle.api.tasks.PathSensitivity;
|
|
||||||
import org.gradle.api.tasks.Sync;
|
|
||||||
|
|
||||||
import org.springframework.boot.build.artifacts.ArtifactRelease;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Conventions that are applied in the presence of the {@link AsciidoctorJPlugin}. When
|
|
||||||
* the plugin is applied:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li>All warnings are made fatal.
|
|
||||||
* <li>The version of AsciidoctorJ is upgraded to 2.4.3.
|
|
||||||
* <li>An {@code asciidoctorExtensions} configuration is created.
|
|
||||||
* <li>For each {@link AsciidoctorTask} (HTML only):
|
|
||||||
* <ul>
|
|
||||||
* <li>A task is created to sync the documentation resources to its output directory.
|
|
||||||
* <li>{@code doctype} {@link AsciidoctorTask#options(Map) option} is configured.
|
|
||||||
* <li>The {@code backend} is configured.
|
|
||||||
* </ul>
|
|
||||||
* <li>For each {@link AbstractAsciidoctorTask} (HTML and PDF):
|
|
||||||
* <ul>
|
|
||||||
* <li>{@link AsciidoctorTask#attributes(Map) Attributes} are configured to enable
|
|
||||||
* warnings for references to missing attributes, the GitHub tag, the Artifactory repo for
|
|
||||||
* the current version, etc.
|
|
||||||
* <li>{@link AbstractAsciidoctorTask#baseDirFollowsSourceDir() baseDirFollowsSourceDir()}
|
|
||||||
* is enabled.
|
|
||||||
* <li>{@code asciidoctorExtensions} is added to the task's configurations.
|
|
||||||
* </ul>
|
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* @author Andy Wilkinson
|
|
||||||
* @author Scott Frederick
|
|
||||||
*/
|
|
||||||
class AsciidoctorConventions {
|
|
||||||
|
|
||||||
private static final String ASCIIDOCTORJ_VERSION = "2.4.3";
|
|
||||||
|
|
||||||
private static final String EXTENSIONS_CONFIGURATION_NAME = "asciidoctorExtensions";
|
|
||||||
|
|
||||||
void apply(Project project) {
|
|
||||||
project.getPlugins().withType(AsciidoctorJPlugin.class, (asciidoctorPlugin) -> {
|
|
||||||
makeAllWarningsFatal(project);
|
|
||||||
upgradeAsciidoctorJVersion(project);
|
|
||||||
createAsciidoctorExtensionsConfiguration(project);
|
|
||||||
project.getTasks()
|
|
||||||
.withType(AbstractAsciidoctorTask.class,
|
|
||||||
(asciidoctorTask) -> configureAsciidoctorTask(project, asciidoctorTask));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void makeAllWarningsFatal(Project project) {
|
|
||||||
project.getExtensions().getByType(AsciidoctorJExtension.class).fatalWarnings(".*");
|
|
||||||
}
|
|
||||||
|
|
||||||
private void upgradeAsciidoctorJVersion(Project project) {
|
|
||||||
project.getExtensions().getByType(AsciidoctorJExtension.class).setVersion(ASCIIDOCTORJ_VERSION);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createAsciidoctorExtensionsConfiguration(Project project) {
|
|
||||||
project.getConfigurations().create(EXTENSIONS_CONFIGURATION_NAME, (configuration) -> {
|
|
||||||
project.getConfigurations()
|
|
||||||
.matching((candidate) -> "dependencyManagement".equals(candidate.getName()))
|
|
||||||
.all(configuration::extendsFrom);
|
|
||||||
configuration.getDependencies()
|
|
||||||
.add(project.getDependencies()
|
|
||||||
.create("io.spring.asciidoctor.backends:spring-asciidoctor-backends:0.0.5"));
|
|
||||||
configuration.getDependencies()
|
|
||||||
.add(project.getDependencies().create("org.asciidoctor:asciidoctorj-pdf:1.5.3"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureAsciidoctorTask(Project project, AbstractAsciidoctorTask asciidoctorTask) {
|
|
||||||
asciidoctorTask.configurations(EXTENSIONS_CONFIGURATION_NAME);
|
|
||||||
configureCommonAttributes(project, asciidoctorTask);
|
|
||||||
configureOptions(asciidoctorTask);
|
|
||||||
configureForkOptions(asciidoctorTask);
|
|
||||||
asciidoctorTask.baseDirFollowsSourceDir();
|
|
||||||
createSyncDocumentationSourceTask(project, asciidoctorTask);
|
|
||||||
if (asciidoctorTask instanceof AsciidoctorTask task) {
|
|
||||||
boolean pdf = task.getName().toLowerCase().contains("pdf");
|
|
||||||
String backend = (!pdf) ? "spring-html" : "spring-pdf";
|
|
||||||
task.outputOptions((outputOptions) -> outputOptions.backends(backend));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureCommonAttributes(Project project, AbstractAsciidoctorTask asciidoctorTask) {
|
|
||||||
ArtifactRelease artifacts = ArtifactRelease.forProject(project);
|
|
||||||
Map<String, Object> attributes = new HashMap<>();
|
|
||||||
attributes.put("attribute-missing", "warn");
|
|
||||||
attributes.put("github-tag", determineGitHubTag(project));
|
|
||||||
attributes.put("artifact-release-type", artifacts.getType());
|
|
||||||
attributes.put("artifact-download-repo", artifacts.getDownloadRepo());
|
|
||||||
attributes.put("revnumber", null);
|
|
||||||
asciidoctorTask.attributes(attributes);
|
|
||||||
}
|
|
||||||
|
|
||||||
// See https://github.com/asciidoctor/asciidoctor-gradle-plugin/issues/597
|
|
||||||
private void configureForkOptions(AbstractAsciidoctorTask asciidoctorTask) {
|
|
||||||
if (JavaVersion.current().isCompatibleWith(JavaVersion.VERSION_16)) {
|
|
||||||
asciidoctorTask.forkOptions((options) -> options.jvmArgs("--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED",
|
|
||||||
"--add-opens", "java.base/java.io=ALL-UNNAMED"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private String determineGitHubTag(Project project) {
|
|
||||||
String version = "v" + project.getVersion();
|
|
||||||
return (version.endsWith("-SNAPSHOT")) ? "main" : version;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void configureOptions(AbstractAsciidoctorTask asciidoctorTask) {
|
|
||||||
asciidoctorTask.options(Collections.singletonMap("doctype", "book"));
|
|
||||||
}
|
|
||||||
|
|
||||||
private Sync createSyncDocumentationSourceTask(Project project, AbstractAsciidoctorTask asciidoctorTask) {
|
|
||||||
Sync syncDocumentationSource = project.getTasks()
|
|
||||||
.create("syncDocumentationSourceFor" + StringUtils.capitalize(asciidoctorTask.getName()), Sync.class);
|
|
||||||
File syncedSource = new File(project.getBuildDir(), "docs/src/" + asciidoctorTask.getName());
|
|
||||||
syncDocumentationSource.setDestinationDir(syncedSource);
|
|
||||||
syncDocumentationSource.from("src/docs/");
|
|
||||||
asciidoctorTask.dependsOn(syncDocumentationSource);
|
|
||||||
asciidoctorTask.getInputs()
|
|
||||||
.dir(syncedSource)
|
|
||||||
.withPathSensitivity(PathSensitivity.RELATIVE)
|
|
||||||
.withPropertyName("synced source");
|
|
||||||
asciidoctorTask.setSourceDir(project.relativePath(new File(syncedSource, "asciidoc/")));
|
|
||||||
return syncDocumentationSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -16,7 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.boot.build;
|
package org.springframework.boot.build;
|
||||||
|
|
||||||
import org.asciidoctor.gradle.jvm.AsciidoctorJPlugin;
|
import org.antora.gradle.AntoraPlugin;
|
||||||
import org.gradle.api.Plugin;
|
import org.gradle.api.Plugin;
|
||||||
import org.gradle.api.Project;
|
import org.gradle.api.Project;
|
||||||
import org.gradle.api.plugins.JavaBasePlugin;
|
import org.gradle.api.plugins.JavaBasePlugin;
|
||||||
@ -32,8 +32,8 @@ import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
|
|||||||
* When the {@link MavenPublishPlugin} is applied, the conventions in
|
* When the {@link MavenPublishPlugin} is applied, the conventions in
|
||||||
* {@link MavenPublishingConventions} are applied.
|
* {@link MavenPublishingConventions} are applied.
|
||||||
*
|
*
|
||||||
* When the {@link AsciidoctorJPlugin} is applied, the conventions in
|
* When the {@link AntoraPlugin} is applied, the conventions in {@link AntoraConventions}
|
||||||
* {@link AsciidoctorConventions} are applied.
|
* are applied.
|
||||||
*
|
*
|
||||||
* @author Andy Wilkinson
|
* @author Andy Wilkinson
|
||||||
* @author Christoph Dreis
|
* @author Christoph Dreis
|
||||||
@ -46,7 +46,7 @@ public class ConventionsPlugin implements Plugin<Project> {
|
|||||||
new NoHttpConventions().apply(project);
|
new NoHttpConventions().apply(project);
|
||||||
new JavaConventions().apply(project);
|
new JavaConventions().apply(project);
|
||||||
new MavenPublishingConventions().apply(project);
|
new MavenPublishingConventions().apply(project);
|
||||||
new AsciidoctorConventions().apply(project);
|
new AntoraConventions().apply(project);
|
||||||
new KotlinConventions().apply(project);
|
new KotlinConventions().apply(project);
|
||||||
new WarConventions().apply(project);
|
new WarConventions().apply(project);
|
||||||
new EclipseConventions().apply(project);
|
new EclipseConventions().apply(project);
|
||||||
|
@ -0,0 +1,162 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build.antora;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
|
||||||
|
import org.springframework.boot.build.artifacts.ArtifactRelease;
|
||||||
|
import org.springframework.boot.build.bom.BomExtension;
|
||||||
|
import org.springframework.boot.build.bom.Library;
|
||||||
|
import org.springframework.util.Assert;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generates Asciidoctor attributes for use with Antora.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public class AntoraAsciidocAttributes {
|
||||||
|
|
||||||
|
private static final String DASH_SNAPSHOT = "-SNAPSHOT";
|
||||||
|
|
||||||
|
private final String version;
|
||||||
|
|
||||||
|
private final boolean latestVersion;
|
||||||
|
|
||||||
|
private final ArtifactRelease artifactRelease;
|
||||||
|
|
||||||
|
private final List<Library> libraries;
|
||||||
|
|
||||||
|
private final Map<String, String> dependencyVersions;
|
||||||
|
|
||||||
|
private final Map<String, ?> projectProperties;
|
||||||
|
|
||||||
|
public AntoraAsciidocAttributes(Project project, BomExtension dependencyBom,
|
||||||
|
Map<String, String> dependencyVersions) {
|
||||||
|
this.version = String.valueOf(project.getVersion());
|
||||||
|
this.latestVersion = Boolean.valueOf(String.valueOf(project.findProperty("latestVersion")));
|
||||||
|
this.artifactRelease = ArtifactRelease.forProject(project);
|
||||||
|
this.libraries = dependencyBom.getLibraries();
|
||||||
|
this.dependencyVersions = dependencyVersions;
|
||||||
|
this.projectProperties = project.getProperties();
|
||||||
|
}
|
||||||
|
|
||||||
|
AntoraAsciidocAttributes(String version, boolean latestVersion, List<Library> libraries,
|
||||||
|
Map<String, String> dependencyVersions, Map<String, ?> projectProperties) {
|
||||||
|
this.version = version;
|
||||||
|
this.latestVersion = latestVersion;
|
||||||
|
this.artifactRelease = ArtifactRelease.forVersion(version);
|
||||||
|
this.libraries = (libraries != null) ? libraries : Collections.emptyList();
|
||||||
|
this.dependencyVersions = (dependencyVersions != null) ? dependencyVersions : Collections.emptyMap();
|
||||||
|
this.projectProperties = (projectProperties != null) ? projectProperties : Collections.emptyMap();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> get() {
|
||||||
|
Map<String, String> attributes = new LinkedHashMap<>();
|
||||||
|
addGitHubAttributes(attributes);
|
||||||
|
addVersionAttributes(attributes);
|
||||||
|
addUrlArtifactRepository(attributes);
|
||||||
|
addUrlLibraryLinkAttributes(attributes);
|
||||||
|
addPropertyAttributes(attributes);
|
||||||
|
return attributes;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addGitHubAttributes(Map<String, String> attributes) {
|
||||||
|
attributes.put("github-repo", "spring-projects/spring-boot");
|
||||||
|
attributes.put("github-ref", determineGitHubRef());
|
||||||
|
}
|
||||||
|
|
||||||
|
private String determineGitHubRef() {
|
||||||
|
int snapshotIndex = this.version.lastIndexOf(DASH_SNAPSHOT);
|
||||||
|
if (snapshotIndex == -1) {
|
||||||
|
return "v" + this.version;
|
||||||
|
}
|
||||||
|
if (this.latestVersion) {
|
||||||
|
return "main";
|
||||||
|
}
|
||||||
|
String versionRoot = this.version.substring(0, snapshotIndex);
|
||||||
|
int lastDot = versionRoot.lastIndexOf('.');
|
||||||
|
return versionRoot.substring(0, lastDot) + ".x";
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addVersionAttributes(Map<String, String> attributes) {
|
||||||
|
this.libraries.forEach((library) -> {
|
||||||
|
String name = "version-" + library.getLinkRootName();
|
||||||
|
String value = library.getVersion().toString();
|
||||||
|
attributes.put(name, value);
|
||||||
|
});
|
||||||
|
attributes.put("version-native-build-tools", (String) this.projectProperties.get("nativeBuildToolsVersion"));
|
||||||
|
attributes.put("version-graal", (String) this.projectProperties.get("graalVersion"));
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-commons");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-couchbase");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-elasticsearch");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-jdbc");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-jpa");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-mongodb");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-neo4j");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-r2dbc");
|
||||||
|
addSpringDataDependencyVersion(attributes, "spring-data-rest", "spring-data-rest-core");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSpringDataDependencyVersion(Map<String, String> attributes, String artifactId) {
|
||||||
|
addSpringDataDependencyVersion(attributes, artifactId, artifactId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSpringDataDependencyVersion(Map<String, String> attributes, String name, String artifactId) {
|
||||||
|
String version = this.dependencyVersions.get("org.springframework.data:" + artifactId);
|
||||||
|
Assert.notNull(version, () -> "No version found for Spring Data artificat " + artifactId);
|
||||||
|
attributes.put("version-" + name, version);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUrlArtifactRepository(Map<String, String> attributes) {
|
||||||
|
attributes.put("url-artifact-repository", this.artifactRelease.getDownloadRepo());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUrlLibraryLinkAttributes(Map<String, String> attributes) {
|
||||||
|
this.libraries.forEach((library) -> {
|
||||||
|
String prefix = "url-" + library.getLinkRootName() + "-";
|
||||||
|
library.getLinks().forEach((name, link) -> attributes.put(prefix + name, link));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addPropertyAttributes(Map<String, String> attributes) {
|
||||||
|
Properties properties = new Properties() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public synchronized Object put(Object key, Object value) {
|
||||||
|
// Put directly because order is important for us
|
||||||
|
return attributes.put(key.toString(), value.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
try (InputStream in = getClass().getResourceAsStream("antora-asciidoc-attributes.properties")) {
|
||||||
|
properties.load(in);
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new UncheckedIOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,197 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build.antora;
|
||||||
|
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Antora and Asciidoc extensions used by Spring Boot.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public final class Extensions {
|
||||||
|
|
||||||
|
private static final String ROOT_COMPONENT_EXTENSION = "@springio/antora-extensions/root-component-extension";
|
||||||
|
|
||||||
|
private static final List<Extension> antora;
|
||||||
|
static {
|
||||||
|
List<Extension> extensions = new ArrayList<>();
|
||||||
|
extensions.add(new Extension("@springio/antora-extensions", "1.8.2", ROOT_COMPONENT_EXTENSION,
|
||||||
|
"@springio/antora-extensions/static-page-extension"));
|
||||||
|
extensions.add(new Extension("@springio/antora-xref-extension", "1.0.0-alpha.3"));
|
||||||
|
extensions.add(new Extension("@springio/antora-zip-contents-collector-extension", "1.0.0-alpha.2"));
|
||||||
|
antora = List.copyOf(extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final List<Extension> asciidoc;
|
||||||
|
static {
|
||||||
|
List<Extension> extensions = new ArrayList<>();
|
||||||
|
extensions.add(new Extension("@asciidoctor/tabs", "1.0.0-beta.6"));
|
||||||
|
extensions
|
||||||
|
.add(new Extension("@springio/asciidoctor-extensions", "1.0.0-alpha.10", "@springio/asciidoctor-extensions",
|
||||||
|
"@springio/asciidoctor-extensions/configuration-properties-extension",
|
||||||
|
"@springio/asciidoctor-extensions/section-ids-extension"));
|
||||||
|
asciidoc = List.copyOf(extensions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static final Map<String, String> localOverrides = Collections.emptyMap();
|
||||||
|
|
||||||
|
private Extensions() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Map<String, String> packages() {
|
||||||
|
Map<String, String> packages = new TreeMap<>();
|
||||||
|
antora.stream().forEach((extension) -> packages.put(extension.name(), extension.version()));
|
||||||
|
asciidoc.stream().forEach((extension) -> packages.put(extension.name(), extension.version()));
|
||||||
|
return Collections.unmodifiableMap(packages);
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<Map<String, Object>> antora(Consumer<AntoraExtensionsConfiguration> extensions) {
|
||||||
|
AntoraExtensionsConfiguration result = new AntoraExtensionsConfiguration(
|
||||||
|
antora.stream().flatMap(Extension::names).sorted().toList());
|
||||||
|
extensions.accept(result);
|
||||||
|
return result.config();
|
||||||
|
}
|
||||||
|
|
||||||
|
static List<String> asciidoc() {
|
||||||
|
return asciidoc.stream().flatMap(Extension::names).sorted().toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private record Extension(String name, String version, String... includeNames) {
|
||||||
|
|
||||||
|
Stream<String> names() {
|
||||||
|
return (this.includeNames.length != 0) ? Arrays.stream(this.includeNames) : Stream.of(this.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static final class AntoraExtensionsConfiguration {
|
||||||
|
|
||||||
|
private Map<String, Map<String, Object>> extensions = new TreeMap<>();
|
||||||
|
|
||||||
|
private AntoraExtensionsConfiguration(List<String> names) {
|
||||||
|
names.forEach((name) -> this.extensions.put(name, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
void xref(Consumer<Xref> xref) {
|
||||||
|
xref.accept(new Xref());
|
||||||
|
}
|
||||||
|
|
||||||
|
void zipContentsCollector(Consumer<ZipContentsCollector> zipContentsCollector) {
|
||||||
|
zipContentsCollector.accept(new ZipContentsCollector());
|
||||||
|
}
|
||||||
|
|
||||||
|
void rootComponent(Consumer<RootComponent> rootComponent) {
|
||||||
|
rootComponent.accept(new RootComponent());
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, Object>> config() {
|
||||||
|
List<Map<String, Object>> config = new ArrayList<>();
|
||||||
|
Map<String, Map<String, Object>> orderedExtensions = new LinkedHashMap<>(this.extensions);
|
||||||
|
// The root component extension must be last
|
||||||
|
Map<String, Object> rootComponentConfig = orderedExtensions.remove(ROOT_COMPONENT_EXTENSION);
|
||||||
|
orderedExtensions.put(ROOT_COMPONENT_EXTENSION, rootComponentConfig);
|
||||||
|
orderedExtensions.forEach((name, customizations) -> {
|
||||||
|
Map<String, Object> extensionConfig = new LinkedHashMap<>();
|
||||||
|
extensionConfig.put("require", localOverrides.getOrDefault(name, name));
|
||||||
|
if (customizations != null) {
|
||||||
|
extensionConfig.putAll(customizations);
|
||||||
|
}
|
||||||
|
config.add(extensionConfig);
|
||||||
|
});
|
||||||
|
return List.copyOf(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class Customizer {
|
||||||
|
|
||||||
|
private final String name;
|
||||||
|
|
||||||
|
Customizer(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void customize(String key, Object value) {
|
||||||
|
AntoraExtensionsConfiguration.this.extensions.computeIfAbsent(this.name, (name) -> new TreeMap<>())
|
||||||
|
.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Xref extends Customizer {
|
||||||
|
|
||||||
|
Xref() {
|
||||||
|
super("@springio/antora-xref-extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
void stub(List<String> stub) {
|
||||||
|
if (stub != null && !stub.isEmpty()) {
|
||||||
|
customize("stub", stub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ZipContentsCollector extends Customizer {
|
||||||
|
|
||||||
|
ZipContentsCollector() {
|
||||||
|
super("@springio/antora-zip-contents-collector-extension");
|
||||||
|
}
|
||||||
|
|
||||||
|
void versionFile(String versionFile) {
|
||||||
|
customize("version_file", versionFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void locations(Path... locations) {
|
||||||
|
locations(Arrays.stream(locations).map(Path::toString).toList());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void locations(List<String> locations) {
|
||||||
|
customize("locations", locations);
|
||||||
|
}
|
||||||
|
|
||||||
|
void alwaysInclude(Map<String, String> alwaysInclude) {
|
||||||
|
if (alwaysInclude != null && !alwaysInclude.isEmpty()) {
|
||||||
|
customize("always_include", List.of(new TreeMap<>(alwaysInclude)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RootComponent extends Customizer {
|
||||||
|
|
||||||
|
RootComponent() {
|
||||||
|
super(ROOT_COMPONENT_EXTENSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
void name(String name) {
|
||||||
|
customize("root_component_name", name);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build.antora;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.UncheckedIOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import org.gradle.api.DefaultTask;
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.artifacts.ProjectDependency;
|
||||||
|
import org.gradle.api.file.RegularFileProperty;
|
||||||
|
import org.gradle.api.provider.ListProperty;
|
||||||
|
import org.gradle.api.provider.MapProperty;
|
||||||
|
import org.gradle.api.provider.Property;
|
||||||
|
import org.gradle.api.tasks.Input;
|
||||||
|
import org.gradle.api.tasks.Optional;
|
||||||
|
import org.gradle.api.tasks.OutputFile;
|
||||||
|
import org.gradle.api.tasks.TaskAction;
|
||||||
|
import org.yaml.snakeyaml.DumperOptions;
|
||||||
|
import org.yaml.snakeyaml.Yaml;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Task to generate a local Antora playbook.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
public abstract class GenerateAntoraPlaybook extends DefaultTask {
|
||||||
|
|
||||||
|
private static final String ANTORA_SOURCE_DIR = "src/docs/antora";
|
||||||
|
|
||||||
|
private static final String GENERATED_DOCS = "build/generated/docs/";
|
||||||
|
|
||||||
|
@OutputFile
|
||||||
|
public abstract RegularFileProperty getOutputFile();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
public abstract Property<String> getContentSourceConfiguration();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
public abstract ListProperty<String> getXrefStubs();
|
||||||
|
|
||||||
|
@Input
|
||||||
|
@Optional
|
||||||
|
public abstract MapProperty<String, String> getAlwaysInclude();
|
||||||
|
|
||||||
|
public GenerateAntoraPlaybook() {
|
||||||
|
setGroup("Documentation");
|
||||||
|
setDescription("Generates an Antora playbook.yml file for local use");
|
||||||
|
getOutputFile().convention(getProject().getLayout()
|
||||||
|
.getBuildDirectory()
|
||||||
|
.file("generated/docs/antora-playbook/antora-playbook.yml"));
|
||||||
|
getContentSourceConfiguration().convention("antoraContent");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TaskAction
|
||||||
|
public void writePlaybookYml() throws IOException {
|
||||||
|
File file = getOutputFile().get().getAsFile();
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
try (FileWriter out = new FileWriter(file)) {
|
||||||
|
createYaml().dump(getData(), out);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Input
|
||||||
|
final Map<String, Object> getData() throws IOException {
|
||||||
|
Map<String, Object> data = loadPlaybookTemplate();
|
||||||
|
addExtensions(data);
|
||||||
|
addSources(data);
|
||||||
|
addDir(data);
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Map<String, Object> loadPlaybookTemplate() throws IOException {
|
||||||
|
try (InputStream resource = getClass().getResourceAsStream("antora-playbook-template.yml")) {
|
||||||
|
return createYaml().loadAs(resource, LinkedHashMap.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void addExtensions(Map<String, Object> data) {
|
||||||
|
Map<String, Object> antora = (Map<String, Object>) data.get("antora");
|
||||||
|
antora.put("extensions", Extensions.antora((extensions) -> {
|
||||||
|
extensions.xref((xref) -> xref.stub(getXrefStubs().getOrElse(Collections.emptyList())));
|
||||||
|
extensions.zipContentsCollector((zipContentsCollector) -> {
|
||||||
|
zipContentsCollector.versionFile("gradle.properties");
|
||||||
|
String locationName = getProject().getName() + "-${version}-${name}-${classifier}.zip";
|
||||||
|
Path antoraContent = getRelativeProjectPath()
|
||||||
|
.resolve(GENERATED_DOCS + "antora-content/" + locationName);
|
||||||
|
Path antoraDepenencies = getRelativeProjectPath()
|
||||||
|
.resolve(GENERATED_DOCS + "antora-dependencies-content/" + locationName);
|
||||||
|
zipContentsCollector.locations(antoraContent, antoraDepenencies);
|
||||||
|
zipContentsCollector.alwaysInclude(getAlwaysInclude().getOrNull());
|
||||||
|
});
|
||||||
|
extensions.rootComponent((rootComponent) -> rootComponent.name("spring-boot"));
|
||||||
|
}));
|
||||||
|
Map<String, Object> asciidoc = (Map<String, Object>) data.get("asciidoc");
|
||||||
|
asciidoc.put("extensions", Extensions.asciidoc());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSources(Map<String, Object> data) {
|
||||||
|
List<Map<String, Object>> contentSources = getList(data, "content.sources");
|
||||||
|
contentSources.add(createContentSource());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> createContentSource() {
|
||||||
|
Map<String, Object> source = new LinkedHashMap<>();
|
||||||
|
Path playbookPath = getOutputFile().get().getAsFile().toPath().getParent();
|
||||||
|
Path antoraSrc = getProjectPath(getProject()).resolve(ANTORA_SOURCE_DIR);
|
||||||
|
StringBuilder url = new StringBuilder(".");
|
||||||
|
relativizeFromRootProject(playbookPath).normalize().forEach((path) -> url.append("/.."));
|
||||||
|
source.put("url", url.toString());
|
||||||
|
source.put("branches", "HEAD");
|
||||||
|
source.put("version", getProject().getVersion().toString());
|
||||||
|
Set<String> startPaths = new LinkedHashSet<>();
|
||||||
|
addAntoraContentStartPaths(startPaths);
|
||||||
|
startPaths.add(relativizeFromRootProject(antoraSrc).toString());
|
||||||
|
source.put("start_paths", startPaths.stream().toList());
|
||||||
|
return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addAntoraContentStartPaths(Set<String> startPaths) {
|
||||||
|
Configuration configuration = getProject().getConfigurations().findByName("antoraContent");
|
||||||
|
if (configuration != null) {
|
||||||
|
for (ProjectDependency dependency : configuration.getAllDependencies().withType(ProjectDependency.class)) {
|
||||||
|
Path path = dependency.getDependencyProject().getProjectDir().toPath();
|
||||||
|
startPaths.add(relativizeFromRootProject(path).resolve(ANTORA_SOURCE_DIR).toString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addDir(Map<String, Object> data) {
|
||||||
|
Path playbookDir = toRealPath(getOutputFile().get().getAsFile().toPath()).getParent();
|
||||||
|
Path outputDir = toRealPath(getProject().getBuildDir().toPath().resolve("site"));
|
||||||
|
data.put("output", Map.of("dir", "./" + playbookDir.relativize(outputDir).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private <T> List<T> getList(Map<String, Object> data, String location) {
|
||||||
|
return (List<T>) get(data, location);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private Object get(Map<String, Object> data, String location) {
|
||||||
|
Object result = data;
|
||||||
|
String[] keys = location.split("\\.");
|
||||||
|
for (String key : keys) {
|
||||||
|
result = ((Map<String, Object>) result).get(key);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Yaml createYaml() {
|
||||||
|
DumperOptions options = new DumperOptions();
|
||||||
|
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||||
|
options.setPrettyFlow(true);
|
||||||
|
return new Yaml(options);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getRelativeProjectPath() {
|
||||||
|
return relativizeFromRootProject(getProjectPath(getProject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path relativizeFromRootProject(Path subPath) {
|
||||||
|
Path rootProjectPath = getProjectPath(getProject().getRootProject());
|
||||||
|
return rootProjectPath.relativize(subPath).normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path getProjectPath(Project project) {
|
||||||
|
return toRealPath(project.getProjectDir().toPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Path toRealPath(Path path) {
|
||||||
|
try {
|
||||||
|
return Files.exists(path) ? path.toRealPath() : path;
|
||||||
|
}
|
||||||
|
catch (IOException ex) {
|
||||||
|
throw new UncheckedIOException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -26,24 +26,18 @@ import org.gradle.api.Project;
|
|||||||
*/
|
*/
|
||||||
public final class ArtifactRelease {
|
public final class ArtifactRelease {
|
||||||
|
|
||||||
private static final String SNAPSHOT = "snapshot";
|
|
||||||
|
|
||||||
private static final String MILESTONE = "milestone";
|
|
||||||
|
|
||||||
private static final String RELEASE = "release";
|
|
||||||
|
|
||||||
private static final String SPRING_REPO = "https://repo.spring.io/%s";
|
private static final String SPRING_REPO = "https://repo.spring.io/%s";
|
||||||
|
|
||||||
private static final String MAVEN_REPO = "https://repo.maven.apache.org/maven2";
|
private static final String MAVEN_REPO = "https://repo.maven.apache.org/maven2";
|
||||||
|
|
||||||
private final String type;
|
private final Type type;
|
||||||
|
|
||||||
private ArtifactRelease(String type) {
|
private ArtifactRelease(Type type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return this.type;
|
return this.type.toString().toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDownloadRepo() {
|
public String getDownloadRepo() {
|
||||||
@ -51,24 +45,34 @@ public final class ArtifactRelease {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRelease() {
|
public boolean isRelease() {
|
||||||
return RELEASE.equals(this.type);
|
return this.type == Type.RELEASE;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ArtifactRelease forProject(Project project) {
|
public static ArtifactRelease forProject(Project project) {
|
||||||
return new ArtifactRelease(determineReleaseType(project));
|
return forVersion(project.getVersion().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String determineReleaseType(Project project) {
|
public static ArtifactRelease forVersion(String version) {
|
||||||
String version = project.getVersion().toString();
|
return new ArtifactRelease(Type.forVersion(version));
|
||||||
int modifierIndex = version.lastIndexOf('-');
|
}
|
||||||
if (modifierIndex == -1) {
|
|
||||||
return RELEASE;
|
enum Type {
|
||||||
|
|
||||||
|
SNAPSHOT, MILESTONE, RELEASE;
|
||||||
|
|
||||||
|
static Type forVersion(String version) {
|
||||||
|
int modifierIndex = version.lastIndexOf('-');
|
||||||
|
if (modifierIndex == -1) {
|
||||||
|
return RELEASE;
|
||||||
|
}
|
||||||
|
String type = version.substring(modifierIndex + 1);
|
||||||
|
if (type.startsWith("M") || type.startsWith("RC")) {
|
||||||
|
return MILESTONE;
|
||||||
|
}
|
||||||
|
return SNAPSHOT;
|
||||||
|
|
||||||
}
|
}
|
||||||
String type = version.substring(modifierIndex + 1);
|
|
||||||
if (type.startsWith("M") || type.startsWith("RC")) {
|
|
||||||
return MILESTONE;
|
|
||||||
}
|
|
||||||
return SNAPSHOT;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2020 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -89,9 +89,9 @@ public class DocumentAutoConfigurationClasses extends DefaultTask {
|
|||||||
|
|
||||||
for (AutoConfigurationClass autoConfigurationClass : autoConfigurationClasses.classes) {
|
for (AutoConfigurationClass autoConfigurationClass : autoConfigurationClasses.classes) {
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.printf("| {spring-boot-code}/spring-boot-project/%s/src/main/java/%s.java[`%s`]%n",
|
writer.printf("| {code-spring-boot}/spring-boot-project/%s/src/main/java/%s.java[`%s`]%n",
|
||||||
autoConfigurationClasses.module, autoConfigurationClass.path, autoConfigurationClass.name);
|
autoConfigurationClasses.module, autoConfigurationClass.path, autoConfigurationClass.name);
|
||||||
writer.printf("| {spring-boot-api}/%s.html[javadoc]%n", autoConfigurationClass.path);
|
writer.printf("| xref:api:java/%s.html[javadoc]%n", autoConfigurationClass.path);
|
||||||
}
|
}
|
||||||
|
|
||||||
writer.println("|===");
|
writer.println("|===");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -29,6 +29,7 @@ import org.gradle.api.DefaultTask;
|
|||||||
import org.gradle.api.Task;
|
import org.gradle.api.Task;
|
||||||
import org.gradle.api.artifacts.ComponentMetadataDetails;
|
import org.gradle.api.artifacts.ComponentMetadataDetails;
|
||||||
import org.gradle.api.artifacts.Configuration;
|
import org.gradle.api.artifacts.Configuration;
|
||||||
|
import org.gradle.api.artifacts.Dependency;
|
||||||
import org.gradle.api.artifacts.DependencyConstraint;
|
import org.gradle.api.artifacts.DependencyConstraint;
|
||||||
import org.gradle.api.artifacts.DependencyConstraintMetadata;
|
import org.gradle.api.artifacts.DependencyConstraintMetadata;
|
||||||
import org.gradle.api.artifacts.dsl.DependencyHandler;
|
import org.gradle.api.artifacts.dsl.DependencyHandler;
|
||||||
@ -64,10 +65,9 @@ public class ExtractVersionConstraints extends DefaultTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void enforcedPlatform(String projectPath) {
|
public void enforcedPlatform(String projectPath) {
|
||||||
this.configuration.getDependencies()
|
Dependency project = getProject().getDependencies().project(Map.of("path", projectPath));
|
||||||
.add(getProject().getDependencies()
|
Dependency dependency = getProject().getDependencies().enforcedPlatform(project);
|
||||||
.enforcedPlatform(
|
this.configuration.getDependencies().add(dependency);
|
||||||
getProject().getDependencies().project(Collections.singletonMap("path", projectPath))));
|
|
||||||
this.projectPaths.add(projectPath);
|
this.projectPaths.add(projectPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,9 +104,8 @@ public class ExtractVersionConstraints extends DefaultTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void extractVersionProperties(String projectPath) {
|
private void extractVersionProperties(String projectPath) {
|
||||||
Object bom = getProject().project(projectPath).getExtensions().getByName("bom");
|
BomExtension bom = (BomExtension) getProject().project(projectPath).getExtensions().getByName("bom");
|
||||||
BomExtension bomExtension = (BomExtension) bom;
|
for (Library lib : bom.getLibraries()) {
|
||||||
for (Library lib : bomExtension.getLibraries()) {
|
|
||||||
String versionProperty = lib.getVersionProperty();
|
String versionProperty = lib.getVersionProperty();
|
||||||
if (versionProperty != null) {
|
if (versionProperty != null) {
|
||||||
this.versionProperties.add(new VersionProperty(lib.getName(), versionProperty));
|
this.versionProperties.add(new VersionProperty(lib.getName(), versionProperty));
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -102,11 +102,7 @@ class Snippets {
|
|||||||
|
|
||||||
private void writeAsciidoc(Path outputDirectory, Snippet snippet, Asciidoc asciidoc) throws IOException {
|
private void writeAsciidoc(Path outputDirectory, Snippet snippet, Asciidoc asciidoc) throws IOException {
|
||||||
String[] parts = (snippet.getAnchor()).split("\\.");
|
String[] parts = (snippet.getAnchor()).split("\\.");
|
||||||
Path path = outputDirectory;
|
Path path = outputDirectory.resolve(parts[parts.length - 1] + ".adoc");
|
||||||
for (int i = 0; i < parts.length; i++) {
|
|
||||||
String name = (i < parts.length - 1) ? parts[i] : parts[i] + ".adoc";
|
|
||||||
path = path.resolve(name);
|
|
||||||
}
|
|
||||||
createDirectory(path.getParent());
|
createDirectory(path.getParent());
|
||||||
Files.deleteIfExists(path);
|
Files.deleteIfExists(path);
|
||||||
try (OutputStream outputStream = Files.newOutputStream(path)) {
|
try (OutputStream outputStream = Files.newOutputStream(path)) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -50,7 +50,7 @@ public class DocumentDevtoolsPropertyDefaults extends DefaultTask {
|
|||||||
this.outputFile = getProject().getObjects().fileProperty();
|
this.outputFile = getProject().getObjects().fileProperty();
|
||||||
this.outputFile.convention(getProject().getLayout()
|
this.outputFile.convention(getProject().getLayout()
|
||||||
.getBuildDirectory()
|
.getBuildDirectory()
|
||||||
.file("docs/generated/using/devtools-property-defaults.adoc"));
|
.file("generated/docs/using/devtools-property-defaults.adoc"));
|
||||||
Map<String, String> dependency = new HashMap<>();
|
Map<String, String> dependency = new HashMap<>();
|
||||||
dependency.put("path", ":spring-boot-project:spring-boot-devtools");
|
dependency.put("path", ":spring-boot-project:spring-boot-devtools");
|
||||||
dependency.put("configuration", "propertyDefaults");
|
dependency.put("configuration", "propertyDefaults");
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -92,7 +92,7 @@ public class DocumentPluginGoals extends DefaultTask {
|
|||||||
writer.println("| Goal | Description");
|
writer.println("| Goal | Description");
|
||||||
writer.println();
|
writer.println();
|
||||||
for (Mojo mojo : plugin.getMojos()) {
|
for (Mojo mojo : plugin.getMojos()) {
|
||||||
writer.printf("| <<%s,%s:%s>>%n", goalSectionId(mojo), plugin.getGoalPrefix(), mojo.getGoal());
|
writer.printf("| xref:%s[%s:%s]%n", goalSectionId(mojo, false), plugin.getGoalPrefix(), mojo.getGoal());
|
||||||
writer.printf("| %s%n", mojo.getDescription());
|
writer.printf("| %s%n", mojo.getDescription());
|
||||||
writer.println();
|
writer.println();
|
||||||
}
|
}
|
||||||
@ -102,11 +102,9 @@ public class DocumentPluginGoals extends DefaultTask {
|
|||||||
|
|
||||||
private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
|
private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
|
||||||
try (PrintWriter writer = new PrintWriter(new FileWriter(new File(this.outputDir, mojo.getGoal() + ".adoc")))) {
|
try (PrintWriter writer = new PrintWriter(new FileWriter(new File(this.outputDir, mojo.getGoal() + ".adoc")))) {
|
||||||
String sectionId = goalSectionId(mojo);
|
String sectionId = goalSectionId(mojo, true);
|
||||||
writer.println();
|
|
||||||
writer.println();
|
|
||||||
writer.printf("[[%s]]%n", sectionId);
|
writer.printf("[[%s]]%n", sectionId);
|
||||||
writer.printf("= `%s:%s`%n", plugin.getGoalPrefix(), mojo.getGoal());
|
writer.printf("= `%s:%s`%n%n", plugin.getGoalPrefix(), mojo.getGoal());
|
||||||
writer.printf("`%s:%s:%s`%n", plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion());
|
writer.printf("`%s:%s:%s`%n", plugin.getGroupId(), plugin.getArtifactId(), plugin.getVersion());
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.println(mojo.getDescription());
|
writer.println(mojo.getDescription());
|
||||||
@ -114,37 +112,43 @@ public class DocumentPluginGoals extends DefaultTask {
|
|||||||
List<Parameter> requiredParameters = parameters.stream().filter(Parameter::isRequired).toList();
|
List<Parameter> requiredParameters = parameters.stream().filter(Parameter::isRequired).toList();
|
||||||
String detailsSectionId = sectionId + ".parameter-details";
|
String detailsSectionId = sectionId + ".parameter-details";
|
||||||
if (!requiredParameters.isEmpty()) {
|
if (!requiredParameters.isEmpty()) {
|
||||||
|
writer.println();
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.printf("[[%s.required-parameters]]%n", sectionId);
|
writer.printf("[[%s.required-parameters]]%n", sectionId);
|
||||||
writer.println("== Required parameters");
|
writer.println("== Required parameters");
|
||||||
|
writer.println();
|
||||||
writeParametersTable(writer, detailsSectionId, requiredParameters);
|
writeParametersTable(writer, detailsSectionId, requiredParameters);
|
||||||
}
|
}
|
||||||
List<Parameter> optionalParameters = parameters.stream()
|
List<Parameter> optionalParameters = parameters.stream()
|
||||||
.filter((parameter) -> !parameter.isRequired())
|
.filter((parameter) -> !parameter.isRequired())
|
||||||
.toList();
|
.toList();
|
||||||
if (!optionalParameters.isEmpty()) {
|
if (!optionalParameters.isEmpty()) {
|
||||||
|
writer.println();
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.printf("[[%s.optional-parameters]]%n", sectionId);
|
writer.printf("[[%s.optional-parameters]]%n", sectionId);
|
||||||
writer.println("== Optional parameters");
|
writer.println("== Optional parameters");
|
||||||
|
writer.println();
|
||||||
writeParametersTable(writer, detailsSectionId, optionalParameters);
|
writeParametersTable(writer, detailsSectionId, optionalParameters);
|
||||||
}
|
}
|
||||||
writer.println();
|
writer.println();
|
||||||
writer.println();
|
writer.println();
|
||||||
|
writer.println();
|
||||||
writer.printf("[[%s]]%n", detailsSectionId);
|
writer.printf("[[%s]]%n", detailsSectionId);
|
||||||
writer.println("== Parameter details");
|
writer.println("== Parameter details");
|
||||||
|
writer.println();
|
||||||
writeParameterDetails(writer, parameters, detailsSectionId);
|
writeParameterDetails(writer, parameters, detailsSectionId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private String goalSectionId(Mojo mojo) {
|
private String goalSectionId(Mojo mojo, boolean innerReference) {
|
||||||
String goalSection = this.goalSections.get(mojo.getGoal());
|
String goalSection = this.goalSections.get(mojo.getGoal());
|
||||||
if (goalSection == null) {
|
if (goalSection == null) {
|
||||||
throw new IllegalStateException("Goal '" + mojo.getGoal() + "' has not be assigned to a section");
|
throw new IllegalStateException("Goal '" + mojo.getGoal() + "' has not be assigned to a section");
|
||||||
}
|
}
|
||||||
String sectionId = goalSection + "." + mojo.getGoal() + "-goal";
|
String sectionId = goalSection + "." + mojo.getGoal() + "-goal";
|
||||||
return sectionId;
|
return (!innerReference) ? goalSection + "#" + sectionId : sectionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeParametersTable(PrintWriter writer, String detailsSectionId, List<Parameter> parameters) {
|
private void writeParametersTable(PrintWriter writer, String detailsSectionId, List<Parameter> parameters) {
|
||||||
@ -236,10 +240,10 @@ public class DocumentPluginGoals extends DefaultTask {
|
|||||||
|
|
||||||
private String typeNameToJavadocLink(String shortName, String name) {
|
private String typeNameToJavadocLink(String shortName, String name) {
|
||||||
if (name.startsWith("org.springframework.boot.maven")) {
|
if (name.startsWith("org.springframework.boot.maven")) {
|
||||||
return "{spring-boot-docs}/maven-plugin/api/" + typeNameToJavadocPath(name) + ".html[" + shortName + "]";
|
return "xref:maven-plugin:api/java/" + typeNameToJavadocPath(name) + ".html[" + shortName + "]";
|
||||||
}
|
}
|
||||||
if (name.startsWith("org.springframework.boot")) {
|
if (name.startsWith("org.springframework.boot")) {
|
||||||
return "{spring-boot-docs}/api/" + typeNameToJavadocPath(name) + ".html[" + shortName + "]";
|
return "xref:api:java/" + typeNameToJavadocPath(name) + ".html[" + shortName + "]";
|
||||||
}
|
}
|
||||||
return shortName;
|
return shortName;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012-2023 the original author or authors.
|
* Copyright 2012-2024 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -158,7 +158,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
|
|||||||
DocumentPluginGoals task = project.getTasks().create("documentPluginGoals", DocumentPluginGoals.class);
|
DocumentPluginGoals task = project.getTasks().create("documentPluginGoals", DocumentPluginGoals.class);
|
||||||
File pluginXml = new File(generatePluginDescriptorTask.getOutputs().getFiles().getSingleFile(), "plugin.xml");
|
File pluginXml = new File(generatePluginDescriptorTask.getOutputs().getFiles().getSingleFile(), "plugin.xml");
|
||||||
task.setPluginXml(pluginXml);
|
task.setPluginXml(pluginXml);
|
||||||
task.setOutputDir(new File(project.getBuildDir(), "docs/generated/goals/"));
|
task.setOutputDir(new File(project.getBuildDir(), "generated/docs/maven-plugin-goals/"));
|
||||||
task.dependsOn(generatePluginDescriptorTask);
|
task.dependsOn(generatePluginDescriptorTask);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,80 @@
|
|||||||
|
# === INCLUDE-CODE LOCATIONS ===
|
||||||
|
|
||||||
|
include-java=ROOT:example$java/org/springframework/boot/docs
|
||||||
|
include-kotlin= ROOT:example$kotlin/org/springframework/boot/docs
|
||||||
|
|
||||||
|
# === URLs ===
|
||||||
|
|
||||||
|
url-ant-docs=https://ant.apache.org/manual
|
||||||
|
url-buildpacks-docs=https://buildpacks.io/docs
|
||||||
|
url-dynatrace-docs=https://docs.dynatrace.com/docs
|
||||||
|
url-dynatrace-docs-shortlink={url-dynatrace-docs}/shortlink
|
||||||
|
url-github-raw=https://raw.githubusercontent.com/{github-repo}/{github-ref}
|
||||||
|
url-github-issues=https://github.com/{github-repo}/issues
|
||||||
|
url-github-wiki=https://github.com/{github-repo}/wiki
|
||||||
|
url-github=https://github.com/{github-repo}
|
||||||
|
url-graal-docs=https://www.graalvm.org/{version-graal}/reference-manual
|
||||||
|
url-graal-docs-native-image={url-graal-docs}/native-image
|
||||||
|
url-gradle-docs=https://docs.gradle.org/current/userguide
|
||||||
|
url-gradle-docs-application-plugin={url-gradle-docs}/application_plugin.html
|
||||||
|
url-gradle-docs-groovy-plugin={url-gradle-docs}/groovy_plugin.html
|
||||||
|
url-gradle-docs-java-plugin={url-gradle-docs}/java_plugin.html
|
||||||
|
url-gradle-docs-war-plugin={url-gradle-docs}/war_plugin.html
|
||||||
|
url-gradle-dsl=https://docs.gradle.org/current/dsl
|
||||||
|
url-gradle-javadoc=https://docs.gradle.org/current/javadoc
|
||||||
|
url-kotlin-docs-kotlin-plugin={url-kotlin-docs}/using-gradle.html
|
||||||
|
url-micrometer-docs-concepts={url-micrometer-docs}/concepts
|
||||||
|
url-micrometer-docs-implementations={url-micrometer-docs}/implementations
|
||||||
|
url-download-liberica-nik=https://bell-sw.com/pages/downloads/native-image-kit/#/nik-22-17
|
||||||
|
url-native-build-tools-docs=https://graalvm.github.io/native-build-tools/{version-native-build-tools}
|
||||||
|
url-native-build-tools-docs-gradle-plugin={url-native-build-tools-docs}/gradle-plugin.html
|
||||||
|
url-native-build-tools-docs-maven-plugin={url-native-build-tools-docs}/maven-plugin.html
|
||||||
|
url-paketo-docs=https://paketo.io/docs
|
||||||
|
url-paketo-docs-java-buildpack={url-paketo-docs}/buildpacks/language-family-buildpacks/java
|
||||||
|
url-spring-boot-for-apache-geode-docs=https://docs.spring.io/spring-boot-data-geode-build/2.0.x/reference/html5
|
||||||
|
url-spring-boot-for-apache-geode-site=https://github.com/spring-projects/spring-boot-data-geode
|
||||||
|
url-spring-data-cassandra-site=https://spring.io/projects/spring-data-cassandra
|
||||||
|
url-spring-data-commons-javadoc=https://docs.spring.io/spring-data/commons/docs/{version-spring-data-commons}/api
|
||||||
|
url-spring-data-couchbase-docs=https://docs.spring.io/spring-data/couchbase/reference/{version-spring-data-couchbase}
|
||||||
|
url-spring-data-couchbase-site=https://spring.io/projects/spring-data-couchbase
|
||||||
|
url-spring-data-elasticsearch-docs=https://docs.spring.io/spring-data/elasticsearch/reference/{version-spring-data-elasticsearch}
|
||||||
|
url-spring-data-elasticsearch-site=https://spring.io/projects/spring-data-elasticsearch
|
||||||
|
url-spring-data-envers-site=https://spring.io/projects/spring-data-envers
|
||||||
|
url-spring-data-gemfire-site=https://spring.io/projects/spring-data-gemfire
|
||||||
|
url-spring-data-geode-site=https://spring.io/projects/spring-data-geode
|
||||||
|
url-spring-data-jdbc-docs=https://docs.spring.io/spring-data/relational/reference/{version-spring-data-jdbc}
|
||||||
|
url-spring-data-jpa-javadoc=https://docs.spring.io/spring-data/jpa/docs/{version-spring-data-jpa}/api
|
||||||
|
url-spring-data-jpa-site=https://spring.io/projects/spring-jpa
|
||||||
|
url-spring-data-jpa-docs=https://docs.spring.io/spring-data/jpa/reference/{version-spring-data-jpa}
|
||||||
|
url-spring-data-ldap-site=https://spring.io/projects/spring-data-ldap
|
||||||
|
url-spring-data-mongodb-javadoc=https://docs.spring.io/spring-data/mongodb/docs/{version-spring-data-mongodb}/api
|
||||||
|
url-spring-data-mongodb-site=https://spring.io/projects/spring-data-mongodb
|
||||||
|
url-spring-data-mongodb-docs=https://docs.spring.io/spring-data/mongodb/reference/{version-spring-data-mongodb}
|
||||||
|
url-spring-data-neo4j-docs=https://docs.spring.io/spring-data/neo4j/reference/{version-spring-data-neo4j}
|
||||||
|
url-spring-data-neo4j-site=https://spring.io/projects/spring-data-neo4j
|
||||||
|
url-spring-data-r2dbc-javadoc=https://docs.spring.io/spring-data/r2dbc/docs/{version-spring-data-r2dbc}/api
|
||||||
|
url-spring-data-r2dbc-docs=https://docs.spring.io/spring-data/relational/reference/{version-spring-data-r2dbc}
|
||||||
|
url-spring-data-redis-site=https://spring.io/projects/spring-data-redis
|
||||||
|
url-spring-data-rest-javadoc=https://docs.spring.io/spring-data/rest/docs/{version-spring-data-rest}/api
|
||||||
|
url-spring-data-site=https://spring.io/projects/spring-data
|
||||||
|
|
||||||
|
# === API References ===
|
||||||
|
|
||||||
|
apiref-gradle-plugin-boot-build-image=xref:gradle-plugin:api/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.html
|
||||||
|
apiref-gradle-plugin-boot-jar=xref:gradle-plugin:api/java/org/springframework/boot/gradle/tasks/bundling/BootJar.html
|
||||||
|
apiref-gradle-plugin-boot-run=xref:gradle-plugin:api/java/org/springframework/boot/gradle/tasks/run/BootRun.html
|
||||||
|
apiref-gradle-plugin-boot-war=xref:gradle-plugin:api/java/org/springframework/boot/gradle/tasks/bundling/BootWar.html
|
||||||
|
apiref-gradle-plugin-boot-build-info=xref:gradle-plugin:api/java/org/springframework/boot/gradle/tasks/buildinfo/BuildInfo.html
|
||||||
|
apiref-openjdk=https://docs.oracle.com/en/java/javase/17/docs/api
|
||||||
|
|
||||||
|
# === Code Links ===
|
||||||
|
|
||||||
|
code-spring-boot=https://github.com/{github-repo}/tree/{github-ref}
|
||||||
|
code-spring-boot-src={code-spring-boot}/spring-boot-project/spring-boot/src/main/java/org/springframework/boot
|
||||||
|
code-spring-boot-actuator-autoconfigure-src={code-spring-boot}/spring-boot-project/spring-boot-actuator-autoconfigure/src/main/java/org/springframework/boot/actuate/autoconfigure
|
||||||
|
code-spring-boot-actuator-src={code-spring-boot}/spring-boot-project/spring-boot-actuator/src/main/java/org/springframework/boot/actuate
|
||||||
|
code-spring-boot-autoconfigure-src={code-spring-boot}/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure
|
||||||
|
code-spring-boot-devtools-src={code-spring-boot}/spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools
|
||||||
|
code-spring-boot-test-autoconfigure-src={code-spring-boot}/spring-boot-project/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure
|
||||||
|
code-spring-boot-latest=https://github.com/{github-repo}/tree/main
|
||||||
|
|
@ -0,0 +1,27 @@
|
|||||||
|
antora:
|
||||||
|
extensions:
|
||||||
|
site:
|
||||||
|
title: Spring Boot
|
||||||
|
content:
|
||||||
|
sources: []
|
||||||
|
asciidoc:
|
||||||
|
sourcemap: true
|
||||||
|
attributes:
|
||||||
|
chomp: all
|
||||||
|
hide-uri-scheme: '@'
|
||||||
|
page-pagination: ''
|
||||||
|
page-stackoverflow-url: https://stackoverflow.com/tags/spring-boot
|
||||||
|
tabs-sync-option: '@'
|
||||||
|
extensions:
|
||||||
|
- '@asciidoctor/tabs'
|
||||||
|
- '@springio/asciidoctor-extensions'
|
||||||
|
- '@springio/asciidoctor-extensions/configuration-properties-extension'
|
||||||
|
- '@springio/asciidoctor-extensions/section-ids-extension'
|
||||||
|
urls:
|
||||||
|
latest_version_segment: ''
|
||||||
|
runtime:
|
||||||
|
log:
|
||||||
|
failure_level: warn
|
||||||
|
ui:
|
||||||
|
bundle:
|
||||||
|
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.11/ui-bundle.zip
|
@ -0,0 +1,171 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build.antora;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.function.Function;
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
import org.springframework.boot.build.bom.Library;
|
||||||
|
import org.springframework.boot.build.bom.Library.Group;
|
||||||
|
import org.springframework.boot.build.bom.Library.LibraryVersion;
|
||||||
|
import org.springframework.boot.build.bom.Library.ProhibitedVersion;
|
||||||
|
import org.springframework.boot.build.bom.Library.VersionAlignment;
|
||||||
|
import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link AntoraAsciidocAttributes}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class AntoraAsciidocAttributesTests {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void githubRefWhenReleasedVersionIsTag() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("github-ref", "v1.2.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void githubRefWhenLatestSnapshotVersionIsMainBranch() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-SNAPSHOT", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("github-ref", "main");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void githubRefWhenOlderSnapshotVersionIsBranch() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-SNAPSHOT", false, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("github-ref", "1.2.x");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void githubRefWhenOlderSnapshotHotFixVersionIsBranch() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3.1-SNAPSHOT", false, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("github-ref", "1.2.3.x");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void versionReferenceFromLibrary() {
|
||||||
|
Library library = mockLibrary(Collections.emptyMap());
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3.1-SNAPSHOT", false, List.of(library),
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("version-spring-framework", "1.2.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void versionReferenceFromSpringDataDependencyVersion() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("version-spring-data-mongodb", "1.2.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void versionNativeBuildTools() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3", true, null,
|
||||||
|
mockDependencyVersions(), Map.of("nativeBuildToolsVersion", "3.4.5"));
|
||||||
|
assertThat(attributes.get()).containsEntry("version-native-build-tools", "3.4.5");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void urlArtifactReposiroryWhenRelease() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("url-artifact-repository", "https://repo.maven.apache.org/maven2");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void urlArtifactReposiroryWhenMilestone() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-M1", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("url-artifact-repository", "https://repo.spring.io/milestone");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void urlArtifactReposiroryWhenSnapshot() {
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3-SNAPSHOT", true, null,
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("url-artifact-repository", "https://repo.spring.io/snapshot");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void urlLinksFromLibrary() {
|
||||||
|
Map<String, Function<LibraryVersion, String>> links = new LinkedHashMap<>();
|
||||||
|
links.put("site", (version) -> "https://example.com/site/" + version);
|
||||||
|
links.put("docs", (version) -> "https://example.com/docs/" + version);
|
||||||
|
Library library = mockLibrary(links);
|
||||||
|
AntoraAsciidocAttributes attributes = new AntoraAsciidocAttributes("1.2.3.1-SNAPSHOT", false, List.of(library),
|
||||||
|
mockDependencyVersions(), null);
|
||||||
|
assertThat(attributes.get()).containsEntry("url-spring-framework-site", "https://example.com/site/1.2.3")
|
||||||
|
.containsEntry("url-spring-framework-docs", "https://example.com/docs/1.2.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void linksFromProperties() {
|
||||||
|
Map<String, String> attributes = new AntoraAsciidocAttributes("1.2.3-SNAPSHOT", true, null,
|
||||||
|
mockDependencyVersions(), null)
|
||||||
|
.get();
|
||||||
|
assertThat(attributes).containsEntry("include-java", "ROOT:example$java/org/springframework/boot/docs");
|
||||||
|
assertThat(attributes).containsEntry("url-spring-data-cassandra-site",
|
||||||
|
"https://spring.io/projects/spring-data-cassandra");
|
||||||
|
List<String> keys = new ArrayList<>(attributes.keySet());
|
||||||
|
assertThat(keys.indexOf("include-java")).isLessThan(keys.indexOf("code-spring-boot-latest"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Library mockLibrary(Map<String, Function<LibraryVersion, String>> links) {
|
||||||
|
String name = "Spring Framework";
|
||||||
|
String calendarName = null;
|
||||||
|
LibraryVersion version = new LibraryVersion(DependencyVersion.parse("1.2.3"));
|
||||||
|
List<Group> groups = Collections.emptyList();
|
||||||
|
List<ProhibitedVersion> prohibitedVersion = Collections.emptyList();
|
||||||
|
boolean considerSnapshots = false;
|
||||||
|
VersionAlignment versionAlignment = null;
|
||||||
|
String linkRootName = null;
|
||||||
|
Library library = new Library(name, calendarName, version, groups, prohibitedVersion, considerSnapshots,
|
||||||
|
versionAlignment, linkRootName, links);
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> mockDependencyVersions() {
|
||||||
|
Map<String, String> versions = new LinkedHashMap<>();
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-commons");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-couchbase");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-elasticsearch");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-jdbc");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-jpa");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-mongodb");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-neo4j");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-r2dbc");
|
||||||
|
addMockSpringDataVersion(versions, "spring-data-rest-core");
|
||||||
|
return versions;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMockSpringDataVersion(Map<String, String> versions, String artifactId) {
|
||||||
|
versions.put("org.springframework.data:" + artifactId, "1.2.3");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2012-2024 the original author or authors.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* https://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.springframework.boot.build.antora;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.gradle.api.Project;
|
||||||
|
import org.gradle.testfixtures.ProjectBuilder;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.io.TempDir;
|
||||||
|
|
||||||
|
import org.springframework.util.function.ThrowingConsumer;
|
||||||
|
|
||||||
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests for {@link GenerateAntoraPlaybook}.
|
||||||
|
*
|
||||||
|
* @author Phillip Webb
|
||||||
|
*/
|
||||||
|
class GenerateAntoraPlaybookTests {
|
||||||
|
|
||||||
|
@TempDir
|
||||||
|
File temp;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void writePlaybookGeneratesExpectedContent() throws Exception {
|
||||||
|
writePlaybookYml((task) -> {
|
||||||
|
task.getXrefStubs().addAll("appendix:.*", "api:.*", "reference:.*");
|
||||||
|
task.getAlwaysInclude().set(Map.of("name", "test", "classifier", "local-aggregate-content"));
|
||||||
|
});
|
||||||
|
Path actual = this.temp.toPath()
|
||||||
|
.resolve("rootproject/project/build/generated/docs/antora-playbook/antora-playbook.yml");
|
||||||
|
System.out.println(Files.readString(actual));
|
||||||
|
assertThat(actual).hasSameTextualContentAs(
|
||||||
|
Path.of("src/test/resources/org/springframework/boot/build/antora/expected-playbook.yml"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writePlaybookYml(ThrowingConsumer<GenerateAntoraPlaybook> customizer) throws Exception {
|
||||||
|
File rootProjectDir = new File(this.temp, "rootproject").getCanonicalFile();
|
||||||
|
rootProjectDir.mkdirs();
|
||||||
|
Project rootProject = ProjectBuilder.builder().withProjectDir(rootProjectDir).build();
|
||||||
|
File projectDir = new File(rootProjectDir, "project");
|
||||||
|
projectDir.mkdirs();
|
||||||
|
Project project = ProjectBuilder.builder().withProjectDir(projectDir).withParent(rootProject).build();
|
||||||
|
GenerateAntoraPlaybook task = project.getTasks().create("generateAntoraPlaybook", GenerateAntoraPlaybook.class);
|
||||||
|
customizer.accept(task);
|
||||||
|
task.writePlaybookYml();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -153,7 +153,6 @@ class ArchitectureCheckTests {
|
|||||||
Resource root = resolver.getResource("classpath:org/springframework/boot/build/architecture/" + name);
|
Resource root = resolver.getResource("classpath:org/springframework/boot/build/architecture/" + name);
|
||||||
FileSystemUtils.copyRecursively(root.getFile(),
|
FileSystemUtils.copyRecursively(root.getFile(),
|
||||||
new File(projectDir, "classes/org/springframework/boot/build/architecture/" + name));
|
new File(projectDir, "classes/org/springframework/boot/build/architecture/" + name));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private interface Callback<T> {
|
private interface Callback<T> {
|
||||||
|
@ -0,0 +1,50 @@
|
|||||||
|
antora:
|
||||||
|
extensions:
|
||||||
|
- require: '@springio/antora-extensions/static-page-extension'
|
||||||
|
- require: '@springio/antora-xref-extension'
|
||||||
|
stub:
|
||||||
|
- appendix:.*
|
||||||
|
- api:.*
|
||||||
|
- reference:.*
|
||||||
|
- require: '@springio/antora-zip-contents-collector-extension'
|
||||||
|
always_include:
|
||||||
|
- classifier: local-aggregate-content
|
||||||
|
name: test
|
||||||
|
locations:
|
||||||
|
- project/build/generated/docs/antora-content/test-${version}-${name}-${classifier}.zip
|
||||||
|
- project/build/generated/docs/antora-dependencies-content/test-${version}-${name}-${classifier}.zip
|
||||||
|
version_file: gradle.properties
|
||||||
|
- require: '@springio/antora-extensions/root-component-extension'
|
||||||
|
root_component_name: spring-boot
|
||||||
|
site:
|
||||||
|
title: Spring Boot
|
||||||
|
content:
|
||||||
|
sources:
|
||||||
|
- url: ./../../../../..
|
||||||
|
branches: HEAD
|
||||||
|
version: unspecified
|
||||||
|
start_paths:
|
||||||
|
- project/src/docs/antora
|
||||||
|
asciidoc:
|
||||||
|
sourcemap: true
|
||||||
|
attributes:
|
||||||
|
chomp: all
|
||||||
|
hide-uri-scheme: '@'
|
||||||
|
page-pagination: ''
|
||||||
|
page-stackoverflow-url: https://stackoverflow.com/tags/spring-boot
|
||||||
|
tabs-sync-option: '@'
|
||||||
|
extensions:
|
||||||
|
- '@asciidoctor/tabs'
|
||||||
|
- '@springio/asciidoctor-extensions'
|
||||||
|
- '@springio/asciidoctor-extensions/configuration-properties-extension'
|
||||||
|
- '@springio/asciidoctor-extensions/section-ids-extension'
|
||||||
|
urls:
|
||||||
|
latest_version_segment: ''
|
||||||
|
runtime:
|
||||||
|
log:
|
||||||
|
failure_level: warn
|
||||||
|
ui:
|
||||||
|
bundle:
|
||||||
|
url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.11/ui-bundle.zip
|
||||||
|
output:
|
||||||
|
dir: ./../../../site
|
@ -1,4 +1,5 @@
|
|||||||
version=3.3.0-SNAPSHOT
|
version=3.3.0-SNAPSHOT
|
||||||
|
latestVersion=true
|
||||||
|
|
||||||
org.gradle.caching=true
|
org.gradle.caching=true
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
@ -6,6 +7,7 @@ org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8
|
|||||||
|
|
||||||
assertjVersion=3.25.3
|
assertjVersion=3.25.3
|
||||||
commonsCodecVersion=1.16.1
|
commonsCodecVersion=1.16.1
|
||||||
|
graalVersion=22.3
|
||||||
hamcrestVersion=2.2
|
hamcrestVersion=2.2
|
||||||
jacksonVersion=2.17.0
|
jacksonVersion=2.17.0
|
||||||
junitJupiterVersion=5.10.2
|
junitJupiterVersion=5.10.2
|
||||||
|
@ -194,14 +194,6 @@ bom {
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
library("Spring Asciidoctor Extensions", "0.6.3") {
|
|
||||||
group("io.spring.asciidoctor") {
|
|
||||||
modules = [
|
|
||||||
"spring-asciidoctor-extensions-spring-boot",
|
|
||||||
"spring-asciidoctor-extensions-section-ids"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
Loading…
Reference in New Issue
Block a user