diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizer.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizer.java new file mode 100644 index 00000000000..456646c24ef --- /dev/null +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizer.java @@ -0,0 +1,44 @@ +/* + * 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 io.spring.start.site.extension.dependency.htmx; + +import io.spring.initializr.generator.buildsystem.Build; +import io.spring.initializr.generator.buildsystem.Dependency; +import io.spring.initializr.generator.spring.build.BuildCustomizer; + +/** + * A {@link BuildCustomizer} that replaces {@code htmx-spring-boot} with + * {@code htmx-spring-boot-thymeleaf} if Thymeleaf is selected. + * + * @author Moritz Halbritter + */ +class HtmxBuildCustomizer implements BuildCustomizer { + + @Override + public void customize(Build build) { + if (build.dependencies().has("thymeleaf")) { + Dependency htmx = build.dependencies().get("htmx"); + build.dependencies().remove("htmx"); + build.dependencies() + .add("htmx-thymeleaf", + Dependency.withCoordinates(htmx.getGroupId(), "htmx-spring-boot-thymeleaf") + .version(htmx.getVersion()) + .build()); + } + } + +} diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxProjectGenerationConfiguration.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxProjectGenerationConfiguration.java new file mode 100644 index 00000000000..7360d24bd9d --- /dev/null +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/HtmxProjectGenerationConfiguration.java @@ -0,0 +1,38 @@ +/* + * 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 io.spring.start.site.extension.dependency.htmx; + +import io.spring.initializr.generator.condition.ConditionalOnRequestedDependency; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +/** + * Configuration for generation of projects that depend on htmx. + * + * @author Moritz Halbritter + */ +@Configuration(proxyBeanMethods = false) +@ConditionalOnRequestedDependency("htmx") +class HtmxProjectGenerationConfiguration { + + @Bean + HtmxBuildCustomizer htmxBuildCustomizer() { + return new HtmxBuildCustomizer(); + } + +} diff --git a/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/package-info.java b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/package-info.java new file mode 100644 index 00000000000..b0e25f8f188 --- /dev/null +++ b/start-site/src/main/java/io/spring/start/site/extension/dependency/htmx/package-info.java @@ -0,0 +1,20 @@ +/* + * Copyright 2012-2022 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. + */ + +/** + * Extensions for generation of projects that depend on htmx. + */ +package io.spring.start.site.extension.dependency.htmx; diff --git a/start-site/src/main/resources/META-INF/spring.factories b/start-site/src/main/resources/META-INF/spring.factories index 28826f662c5..f2a58132499 100644 --- a/start-site/src/main/resources/META-INF/spring.factories +++ b/start-site/src/main/resources/META-INF/spring.factories @@ -13,6 +13,7 @@ io.spring.start.site.extension.dependency.elasticsearch.ElasticsearchProjectGene io.spring.start.site.extension.dependency.flyway.FlywayProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.graalvm.GraalVmProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.graphql.SpringGraphQlProjectGenerationConfiguration,\ +io.spring.start.site.extension.dependency.htmx.HtmxProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.mariadb.MariaDbProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.mongodb.MongoDbProjectGenerationConfiguration,\ io.spring.start.site.extension.dependency.mysql.MysqlProjectGenerationConfiguration,\ diff --git a/start-site/src/main/resources/application.yml b/start-site/src/main/resources/application.yml index 7eb651fbc3e..52faf59e0c8 100644 --- a/start-site/src/main/resources/application.yml +++ b/start-site/src/main/resources/application.yml @@ -348,6 +348,21 @@ initializr: links: - rel: reference href: https://netflix.github.io/dgs/ + - name: htmx + id: htmx + facets: + - web + starter: false + groupId: io.github.wimdeblauwe + artifactId: htmx-spring-boot + description: Build modern user interfaces with the simplicity and power of hypertext. + compatibilityRange: "[3.2.0,3.4.0-M1)" + version: 3.4.1 + links: + - rel: reference + href: https://github.com/wimdeblauwe/htmx-spring-boot + - rel: guide + href: https://www.youtube.com/watch?v=j-rfPoXe5aE - name: Template Engines content: - name: Thymeleaf diff --git a/start-site/src/test/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizerTests.java b/start-site/src/test/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizerTests.java new file mode 100644 index 00000000000..ada2bc088de --- /dev/null +++ b/start-site/src/test/java/io/spring/start/site/extension/dependency/htmx/HtmxBuildCustomizerTests.java @@ -0,0 +1,60 @@ +/* + * 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 io.spring.start.site.extension.dependency.htmx; + +import io.spring.initializr.metadata.Dependency; +import io.spring.initializr.web.project.ProjectRequest; +import io.spring.start.site.extension.AbstractExtensionTests; +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +/** + * Tests for {@link HtmxBuildCustomizer}. + * + * @author Moritz Halbritter + */ +class HtmxBuildCustomizerTests extends AbstractExtensionTests { + + private final Dependency htmx = Dependency.withId("htmx", "io.github.wimdeblauwe", "htmx-spring-boot"); + + private final Dependency htmxThymeleaf = Dependency.withId("htmx", "io.github.wimdeblauwe", + "htmx-spring-boot-thymeleaf"); + + @Test + void shouldUseHtmxThymleafIfThymeleafIsSelected() { + ProjectRequest request = createProjectRequest("htmx", "thymeleaf"); + assertThat(mavenPom(request)).doesNotHaveDependency(this.htmx.getGroupId(), this.htmx.getArtifactId()) + .hasDependency(this.htmxThymeleaf); + } + + @Test + void shouldUsePlainHtmxIfThymeleafIsNotSelected() { + ProjectRequest request = createProjectRequest("htmx"); + assertThat(mavenPom(request)) + .doesNotHaveDependency(this.htmxThymeleaf.getGroupId(), this.htmxThymeleaf.getArtifactId()) + .hasDependency(this.htmx); + } + + @Test + void shouldNotAddHtmx() { + ProjectRequest request = createProjectRequest("web"); + assertThat(mavenPom(request)).doesNotHaveDependency(this.htmx.getGroupId(), this.htmx.getArtifactId()) + .doesNotHaveDependency(this.htmxThymeleaf.getGroupId(), this.htmxThymeleaf.getArtifactId()); + } + +}