Merge pull request #1290 from herder

* pr/1290:
  Polish "Add support for Maven extensions"
  Add support for Maven extensions

Closes gh-1290
This commit is contained in:
Stephane Nicoll 2023-06-12 12:19:55 +02:00
commit d48f7636ed
5 changed files with 245 additions and 2 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2020 the original author or authors.
* 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.
@ -26,6 +26,7 @@ import io.spring.initializr.generator.buildsystem.maven.MavenBuildSettings.Build
*
* @author Andy Wilkinson
* @author Stephane Nicoll
* @author Niklas Herder
*/
public class MavenBuild extends Build {
@ -37,6 +38,8 @@ public class MavenBuild extends Build {
private final MavenPluginContainer plugins = new MavenPluginContainer();
private final MavenExtensionContainer extensions = new MavenExtensionContainer();
private final MavenDistributionManagement.Builder distributionManagement = new MavenDistributionManagement.Builder();
private final MavenProfileContainer profiles;
@ -105,6 +108,15 @@ public class MavenBuild extends Build {
return this.plugins;
}
/**
* Return the {@linkplain MavenExtensionContainer extension container} to use to
* configure extensions.
* @return the {@link MavenExtensionContainer}
*/
public MavenExtensionContainer extensions() {
return this.extensions;
}
/**
* Return the {@linkplain MavenProfileContainer profile container} to use to configure
* profiles.

View File

@ -59,6 +59,7 @@ import org.springframework.util.StringUtils;
* @author Olga Maciaszek-Sharma
* @author Jafer Khan Shamshad
* @author Joachim Pasquali
* @author Niklas Herder
*/
public class MavenBuildWriter {
@ -315,7 +316,8 @@ public class MavenBuildWriter {
MavenBuildSettings settings = build.getSettings();
if (settings.getDefaultGoal() == null && settings.getFinalName() == null
&& settings.getSourceDirectory() == null && settings.getTestSourceDirectory() == null
&& build.resources().isEmpty() && build.testResources().isEmpty() && build.plugins().isEmpty()) {
&& build.resources().isEmpty() && build.testResources().isEmpty() && build.plugins().isEmpty()
&& build.extensions().isEmpty()) {
return;
}
writer.println();
@ -326,6 +328,7 @@ public class MavenBuildWriter {
writeSingleElement(writer, "testSourceDirectory", settings.getTestSourceDirectory());
writeResources(writer, build.resources(), build.testResources());
writeCollectionElement(writer, "plugins", build.plugins().values(), this::writePlugin);
writeCollectionElement(writer, "extensions", build.extensions().values(), this::writeExtension);
});
}
@ -495,6 +498,14 @@ public class MavenBuildWriter {
}
}
private void writeExtension(IndentingWriter writer, MavenExtension extension) {
writeElement(writer, "extension", () -> {
writeSingleElement(writer, "groupId", extension.getGroupId());
writeSingleElement(writer, "artifactId", extension.getArtifactId());
writeSingleElement(writer, "version", extension.getVersion());
});
}
private void writeProfiles(IndentingWriter writer, MavenBuild build) {
MavenProfileContainer profiles = build.profiles();
if (profiles.isEmpty()) {

View File

@ -0,0 +1,96 @@
/*
* 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.initializr.generator.buildsystem.maven;
/**
* A build extension in a @{@link MavenBuild}.
*
* @author Niklas Herder
* @author Stephane Nicoll
*/
public class MavenExtension {
private final String groupId;
private final String artifactId;
private final String version;
protected MavenExtension(Builder builder) {
this.groupId = builder.groupId;
this.artifactId = builder.artifactId;
this.version = builder.version;
}
/**
* Return the group ID of the extension.
* @return the group id
*/
public String getGroupId() {
return this.groupId;
}
/**
* Return the artifact ID of the extension.
* @return the artifact id
*/
public String getArtifactId() {
return this.artifactId;
}
/**
* Return the version of the extension.
* @return the artifact id
*/
public String getVersion() {
return this.version;
}
public static class Builder {
private final String groupId;
private final String artifactId;
private String version;
protected Builder(String groupId, String artifactId) {
this.groupId = groupId;
this.artifactId = artifactId;
}
/**
* Set the version of the extension.
* @param version the version of the extension
* @return this for method chaining
*/
public Builder version(String version) {
this.version = version;
return this;
}
/**
* Build a {@link MavenExtension} with the current state of this builder.
* @return a {@link MavenExtension}
*/
public MavenExtension build() {
return new MavenExtension(this);
}
}
}

View File

@ -0,0 +1,107 @@
/*
* 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.initializr.generator.buildsystem.maven;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.stream.Stream;
/**
* A container for {@link MavenExtension maven extensions}.
*
* @author Niklas Herder
* @author Stephane Nicoll
*/
public class MavenExtensionContainer {
private final Map<String, MavenExtension.Builder> extensions = new LinkedHashMap<>();
/**
* Specify if this container is empty.
* @return {@code true} if no {@link MavenExtension} is added
*/
public boolean isEmpty() {
return this.extensions.isEmpty();
}
/**
* Specify if this container has a extension with the specified {@code groupId} and
* {@code artifactId}.
* @param groupId the groupId of the extension
* @param artifactId the artifactId of the extension
* @return {@code true} if an item with the specified {@code groupId} and
* {@code artifactId} exists
*/
public boolean has(String groupId, String artifactId) {
return this.extensions.containsKey(extensionKey(groupId, artifactId));
}
/**
* Returns a {@link Stream} of registered {@link MavenExtension}s.
* @return a stream of {@link MavenExtension}s
*/
public Stream<MavenExtension> values() {
return this.extensions.values().stream().map(MavenExtension.Builder::build);
}
/**
* Add a {@link MavenExtension} with the specified {@code groupId},
* {@code artifactId}, and {@code version}. If the extension has already been added,
* only update the version if necessary.
* @param groupId the groupId of the extension
* @param artifactId the artifactId of the extension
* @param version the version of the extension
* @see #add(String, String, Consumer)
*/
public void add(String groupId, String artifactId, String version) {
add(groupId, artifactId, (extension) -> extension.version(version));
}
/**
* Add a {@link MavenExtension} with the specified {@code groupId} and
* {@code artifactId} and {@link Consumer} to customize the extension. If the
* extension has already been added, the consumer can be used to further tune the
* existing extension configuration.
* @param groupId the groupId of the extension
* @param artifactId the artifactId of the extension
* @param extension a {@link Consumer} to customize the {@link MavenExtension}
*/
public void add(String groupId, String artifactId, Consumer<MavenExtension.Builder> extension) {
extension.accept(addExtension(groupId, artifactId));
}
private MavenExtension.Builder addExtension(String groupId, String artifactId) {
return this.extensions.computeIfAbsent(extensionKey(groupId, artifactId),
(extensionId) -> new MavenExtension.Builder(groupId, artifactId));
}
/**
* Remove the extension with the specified {@code groupId} and {@code artifactId}.
* @param groupId the groupId of the extension to remove
* @param artifactId the artifactId of the extension to remove
* @return {@code true} if such a extension was registered, {@code false} otherwise
*/
public boolean remove(String groupId, String artifactId) {
return this.extensions.remove(extensionKey(groupId, artifactId)) != null;
}
private String extensionKey(String groupId, String artifactId) {
return String.format("%s:%s", groupId, artifactId);
}
}

View File

@ -700,6 +700,23 @@ class MavenBuildWriterTests {
});
}
@Test
void pomWithoutExtensions() {
MavenBuild build = new MavenBuild();
generatePom(build, (pom) -> assertThat(pom).nodeAtPath("/project/build/extensions").isNull());
}
@Test
void pomWithExtension() {
MavenBuild build = new MavenBuild();
build.extensions().add("com.example", "testExtension", "1.6.1");
generatePom(build, (pom) -> {
assertThat(pom).textAtPath("/project/build/extensions/extension/groupId").isEqualTo("com.example");
assertThat(pom).textAtPath("/project/build/extensions/extension/artifactId").isEqualTo("testExtension");
assertThat(pom).textAtPath("/project/build/extensions/extension/version").isEqualTo("1.6.1");
});
}
@Test
void pomWithEmptyBuild() {
MavenBuild build = new MavenBuild();