From 7f99190259177e5be15cb3c1227c80652b7ce0c3 Mon Sep 17 00:00:00 2001 From: Phillip Webb Date: Wed, 27 Mar 2024 21:42:25 -0700 Subject: [PATCH] Manage antora versions using package.json See gh-40132 --- .gitignore | 1 + antora/package.json | 15 +++++ .../boot/build/AntoraConventions.java | 59 +++++++++++++------ .../boot/build/antora/Extensions.java | 24 +++----- 4 files changed, 65 insertions(+), 34 deletions(-) create mode 100644 antora/package.json diff --git a/.gitignore b/.gitignore index 2a812bc5079..1198c2da875 100644 --- a/.gitignore +++ b/.gitignore @@ -40,3 +40,4 @@ secrets.yml .gradletasknamecache .sts4-cache .git-hooks/ +node_modules diff --git a/antora/package.json b/antora/package.json new file mode 100644 index 00000000000..71d19b7ac1b --- /dev/null +++ b/antora/package.json @@ -0,0 +1,15 @@ +{ + "scripts": { + "antora": "node npm/antora.js" + }, + "dependencies": { + "@antora/cli": "3.2.0-alpha.4", + "@antora/site-generator": "3.2.0-alpha.4", + "@antora/atlas-extension": "1.0.0-alpha.2", + "@springio/antora-extensions": "1.8.2", + "@springio/antora-xref-extension": "1.0.0-alpha.3", + "@springio/antora-zip-contents-collector-extension": "1.0.0-alpha.2", + "@asciidoctor/tabs": "1.0.0-beta.6", + "@springio/asciidoctor-extensions": "1.0.0-alpha.10" + } +} diff --git a/buildSrc/src/main/java/org/springframework/boot/build/AntoraConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/AntoraConventions.java index 6a6af3de9bf..d46e580edea 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/AntoraConventions.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/AntoraConventions.java @@ -17,26 +17,25 @@ package org.springframework.boot.build; import java.io.File; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import com.github.gradle.node.NodeExtension; +import com.github.gradle.node.npm.task.NpmInstallTask; 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.Copy; 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; @@ -51,8 +50,6 @@ 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 NAV_FILES = List.of("nav.adoc", "local-nav.adoc"); @@ -67,18 +64,42 @@ public class AntoraConventions { TaskContainer tasks = project.getTasks(); GenerateAntoraPlaybook generateAntoraPlaybookTask = tasks.create("generateAntoraPlaybook", GenerateAntoraPlaybook.class); + configureGenerateAntoraPlaybookTask(project, generateAntoraPlaybookTask); + Copy copyAntoraPackageJsonTask = tasks.create("copyAntoraPackageJson", Copy.class); + configureCopyAntoraPackageJsonTask(project, copyAntoraPackageJsonTask); + NpmInstallTask npmInstallTask = tasks.create("antoraNpmInstall", NpmInstallTask.class); + configureNpmInstallTask(project, npmInstallTask, copyAntoraPackageJsonTask); 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); - }); + (antoraTask) -> configureAntoraTask(project, antoraTask, npmInstallTask, generateAntoraPlaybookTask)); + project.getExtensions() + .configure(AntoraExtension.class, (antoraExtension) -> configureAntoraExtension(project, antoraExtension)); project.getExtensions() .configure(NodeExtension.class, (nodeExtension) -> configureNodeExtension(project, nodeExtension)); } + private void configureGenerateAntoraPlaybookTask(Project project, + GenerateAntoraPlaybook generateAntoraPlaybookTask) { + File nodeProjectDir = getNodeProjectDir(project.getBuildDir()); + generateAntoraPlaybookTask.getOutputFile().set(new File(nodeProjectDir, "antora-playbook.yml")); + } + + private void configureCopyAntoraPackageJsonTask(Project project, Copy copyAntoraPackageJsonTask) { + copyAntoraPackageJsonTask + .from(project.getRootProject().file("antora"), (spec) -> spec.include("package.json", "package-lock.json")) + .into(getNodeProjectDir(project.getBuildDir())); + } + + private void configureNpmInstallTask(Project project, NpmInstallTask npmInstallTask, Copy copyAntoraPackageJson) { + npmInstallTask.dependsOn(copyAntoraPackageJson); + Map environment = new HashMap<>(); + environment.put("npm_config_omit", "optional"); + environment.put("npm_config_update_notifier", "false"); + npmInstallTask.getEnvironment().set(environment); + npmInstallTask.getNpmCommand().set(List.of("ci")); + } + private ExtractVersionConstraints addDependencyVersionsTask(Project project) { return project.getTasks() .create("dependencyVersions", ExtractVersionConstraints.class, @@ -121,10 +142,11 @@ public class AntoraConventions { return attributes.get(); } - private void configureAntoraTask(Project project, AntoraTask antoraTask, + private void configureAntoraTask(Project project, AntoraTask antoraTask, NpmInstallTask npmInstallTask, GenerateAntoraPlaybook generateAntoraPlaybookTask) { antoraTask.setGroup("Documentation"); - antoraTask.getDependsOn().add(generateAntoraPlaybookTask); + antoraTask.dependsOn(npmInstallTask, generateAntoraPlaybookTask); + antoraTask.setPlaybook("antora-playbook.yml"); project.getPlugins() .withType(JavaBasePlugin.class, (javaBasePlugin) -> project.getTasks() @@ -132,11 +154,7 @@ public class AntoraConventions { .dependsOn(antoraTask)); } - private void configureAntoraExtension(Project project, AntoraExtension antoraExtension, - Provider playbook) { - antoraExtension.getVersion().convention(ANTORA_VERSION); - antoraExtension.getPackages().convention(Extensions.packages()); - antoraExtension.getPlaybook().convention(playbook.map(RegularFile::getAsFile)); + private void configureAntoraExtension(Project project, AntoraExtension antoraExtension) { if (project.getGradle().getStartParameter().getLogLevel() != LogLevel.DEBUG) { antoraExtension.getOptions().add("--quiet"); } @@ -149,6 +167,11 @@ public class AntoraConventions { File buildDir = project.getBuildDir(); nodeExtension.getWorkDir().set(buildDir.toPath().resolve(".gradle/nodejs").toFile()); nodeExtension.getNpmWorkDir().set(buildDir.toPath().resolve(".gradle/npm").toFile()); + nodeExtension.getNodeProjectDir().set(getNodeProjectDir(buildDir)); + } + + private File getNodeProjectDir(File buildDir) { + return buildDir.toPath().resolve(".gradle/nodeproject").toFile(); } } diff --git a/buildSrc/src/main/java/org/springframework/boot/build/antora/Extensions.java b/buildSrc/src/main/java/org/springframework/boot/build/antora/Extensions.java index e56d2b7d8dd..ac11fd6c802 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/antora/Extensions.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/antora/Extensions.java @@ -39,21 +39,20 @@ public final class Extensions { private static final List antora; static { List extensions = new ArrayList<>(); - extensions.add(new Extension("@springio/antora-extensions", "1.8.2", ROOT_COMPONENT_EXTENSION, + extensions.add(new Extension("@springio/antora-extensions", 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.3")); + extensions.add(new Extension("@springio/antora-xref-extension")); + extensions.add(new Extension("@springio/antora-zip-contents-collector-extension")); antora = List.copyOf(extensions); } private static final List asciidoc; static { List 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")); + extensions.add(new Extension("@asciidoctor/tabs")); + extensions.add(new Extension("@springio/asciidoctor-extensions", "@springio/asciidoctor-extensions", + "@springio/asciidoctor-extensions/configuration-properties-extension", + "@springio/asciidoctor-extensions/section-ids-extension")); asciidoc = List.copyOf(extensions); } @@ -62,13 +61,6 @@ public final class Extensions { private Extensions() { } - public static Map packages() { - Map 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> antora(Consumer extensions) { AntoraExtensionsConfiguration result = new AntoraExtensionsConfiguration( antora.stream().flatMap(Extension::names).sorted().toList()); @@ -80,7 +72,7 @@ public final class Extensions { return asciidoc.stream().flatMap(Extension::names).sorted().toList(); } - private record Extension(String name, String version, String... includeNames) { + private record Extension(String name, String... includeNames) { Stream names() { return (this.includeNames.length != 0) ? Arrays.stream(this.includeNames) : Stream.of(this.name);