From 55814fd6cdac15a28ef08b4a3d2bec68a49a9b15 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 10 Nov 2023 14:29:38 +0100 Subject: [PATCH] Generate help section for Testcontainers This help section contains the docker images and tags used for the Testcontainers. --- .../TestContainersHelpDocumentCustomizer.java | 64 +++++++++++++++++++ ...tainersProjectGenerationConfiguration.java | 36 ++++++----- .../templates/testcontainers.mustache | 13 ++++ ...rsProjectGenerationConfigurationTests.java | 11 ++++ 4 files changed, 108 insertions(+), 16 deletions(-) create mode 100644 start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestContainersHelpDocumentCustomizer.java create mode 100644 start-site/src/main/resources/templates/testcontainers.mustache diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestContainersHelpDocumentCustomizer.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestContainersHelpDocumentCustomizer.java new file mode 100644 index 00000000000..91f34224247 --- /dev/null +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestContainersHelpDocumentCustomizer.java @@ -0,0 +1,64 @@ +/* + * Copyright 2012-2023 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 io.spring.start.site.extension.dependency.testcontainers; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.spring.initializr.generator.project.ProjectDescription; +import io.spring.initializr.generator.spring.documentation.HelpDocument; +import io.spring.initializr.generator.spring.documentation.HelpDocumentCustomizer; +import io.spring.start.site.container.DockerService; +import io.spring.start.site.container.ServiceConnections; +import io.spring.start.site.container.ServiceConnections.ServiceConnection; + +/** + * A {@link HelpDocumentCustomizer} that provide additional information about the + * Testcontainers that are defined for the project. + * + * @author Moritz Halbritter + */ +class TestContainersHelpDocumentCustomizer implements HelpDocumentCustomizer { + + private final ProjectDescription description; + + private final ServiceConnections serviceConnections; + + TestContainersHelpDocumentCustomizer(ProjectDescription description, ServiceConnections serviceConnections) { + this.description = description; + this.serviceConnections = serviceConnections; + } + + @Override + public void customize(HelpDocument document) { + String referenceDocUrl = "https://docs.spring.io/spring-boot/docs/%s/reference/html/features.html#features.testing.testcontainers" + .formatted(this.description.getPlatformVersion()); + document.gettingStarted().addReferenceDocLink(referenceDocUrl, "Spring Boot Testcontainers support"); + + Map model = new HashMap<>(); + List dockerServices = this.serviceConnections.values() + .map(ServiceConnection::dockerService) + .toList(); + model.put("services", dockerServices); + model.put("testcontainersAtDevelopmentTimeLink", + "https://docs.spring.io/spring-boot/docs/%s/reference/html/features.html#features.testing.testcontainers.at-development-time" + .formatted(this.description.getPlatformVersion())); + document.addSection("testcontainers", model); + } + +} diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfiguration.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfiguration.java index 701beeb6ea8..2ec09f0a02f 100644 --- a/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfiguration.java +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfiguration.java @@ -29,7 +29,6 @@ import io.spring.initializr.generator.project.ProjectDescription; import io.spring.initializr.generator.project.ProjectGenerationConfiguration; import io.spring.initializr.generator.spring.build.BuildCustomizer; -import io.spring.initializr.generator.spring.documentation.HelpDocumentCustomizer; import io.spring.start.site.container.ServiceConnections; import io.spring.start.site.container.ServiceConnectionsCustomizer; import io.spring.start.site.support.implicit.ImplicitDependency; @@ -39,12 +38,14 @@ import org.springframework.beans.factory.ObjectProvider; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Import; /** * Configuration for generation of projects that depend on Testcontainers. * * @author Maciej Walkowiak * @author Stephane Nicoll + * @author Moritz Halbritter */ @ProjectGenerationConfiguration @ConditionalOnRequestedDependency("testcontainers") @@ -68,6 +69,20 @@ public ImplicitDependencyHelpDocumentCustomizer testcontainersHelpCustomizer(Bui @Configuration(proxyBeanMethods = false) @ConditionalOnPlatformVersion("3.1.0-RC1") + static class ServiceConnectionsConfiguration { + + @Bean + ServiceConnections serviceConnections(ObjectProvider customizers) { + ServiceConnections serviceConnections = new ServiceConnections(); + customizers.orderedStream().forEach((customizer) -> customizer.customize(serviceConnections)); + return serviceConnections; + } + + } + + @Configuration(proxyBeanMethods = false) + @ConditionalOnPlatformVersion("3.1.0-RC1") + @Import(ServiceConnectionsConfiguration.class) static class SpringBootSupportConfiguration { @Bean @@ -80,20 +95,16 @@ BuildCustomizer springBootTestcontainersBuildCustomizer() { } @Bean - HelpDocumentCustomizer springBootTestcontainersHelpDocumentCustomizer(ProjectDescription description) { - return (helpDocument) -> { - String referenceDocUrl = String.format( - "https://docs.spring.io/spring-boot/docs/%s/reference/html/features.html#features.testing.testcontainers", - description.getPlatformVersion()); - helpDocument.gettingStarted() - .addReferenceDocLink(referenceDocUrl, "Spring Boot Testcontainers support"); - }; + TestContainersHelpDocumentCustomizer springBootTestcontainersHelpDocumentCustomizer( + ProjectDescription description, ServiceConnections serviceConnections) { + return new TestContainersHelpDocumentCustomizer(description, serviceConnections); } } @Configuration(proxyBeanMethods = false) @ConditionalOnPlatformVersion("3.1.0-RC1") + @Import(ServiceConnectionsConfiguration.class) static class TestApplicationConfiguration { private final ProjectDescription description; @@ -105,13 +116,6 @@ static class TestApplicationConfiguration { this.indentingWriterFactory = indentingWriterFactory; } - @Bean - ServiceConnections serviceConnections(ObjectProvider customizers) { - ServiceConnections serviceConnections = new ServiceConnections(); - customizers.orderedStream().forEach((customizer) -> customizer.customize(serviceConnections)); - return serviceConnections; - } - @Bean @ConditionalOnLanguage(GroovyLanguage.ID) GroovyTestContainersApplicationCodeProjectContributor groovyTestContainersApplicationCodeProjectContributor( diff --git a/start-site/src/main/resources/templates/testcontainers.mustache b/start-site/src/main/resources/templates/testcontainers.mustache new file mode 100644 index 00000000000..667388cda52 --- /dev/null +++ b/start-site/src/main/resources/templates/testcontainers.mustache @@ -0,0 +1,13 @@ +### Testcontainers support + +This project uses [Testcontainers at development time]({{testcontainersAtDevelopmentTimeLink}}). + +{{#services.size}} +Testcontainers has been configured to use the following Docker images: + +{{#services}} +* [`{{image}}:{{imageTag}}`]({{website}}) +{{/services}} + +Please review the tags of the used images and set them to the same as you're running in production. +{{/services.size}} diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java index cfb811a1358..29426620b64 100644 --- a/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/testcontainers/TestcontainersProjectGenerationConfigurationTests.java @@ -37,6 +37,7 @@ * @author Stephane Nicoll * @author EddĂș MelĂ©ndez * @author Chris Bono + * @author Moritz Halbritter */ class TestcontainersProjectGenerationConfigurationTests extends AbstractExtensionTests { @@ -344,6 +345,16 @@ fun main(args: Array) { """); } + @Test + void shouldAddHelpSection() { + assertHelpDocument("3.1.5", "testcontainers", "data-mongodb", "postgresql").contains( + "https://docs.spring.io/spring-boot/docs/3.1.5/reference/html/features.html#features.testing.testcontainers") + .contains( + "https://docs.spring.io/spring-boot/docs/3.1.5/reference/html/features.html#features.testing.testcontainers.at-development-time") + .contains("mongo:latest") + .contains("postgres:latest"); + } + private ProjectStructure generateProject(String platformVersion, String... dependencies) { ProjectRequest request = createProjectRequest(dependencies); request.setBootVersion(platformVersion);