mirror of
https://gitee.com/dcren/initializr.git
synced 2025-04-05 17:38:06 +08:00
Add Maven build support
This commit provides a Maven build system implementation with a writer that can generate `pom.xml` files based on a configurable model. Closes gh-814 Co-authored-by: Stephane Nicoll <snicoll@pivotal.io>
This commit is contained in:
parent
2bd64ed6ed
commit
3f585337da
@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.Build;
|
||||
import io.spring.initializr.generator.buildsystem.BuildItemResolver;
|
||||
|
||||
/**
|
||||
* Maven build for a project.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class MavenBuild extends Build {
|
||||
|
||||
private MavenParent parent;
|
||||
|
||||
private String name;
|
||||
|
||||
private String description;
|
||||
|
||||
private String sourceDirectory;
|
||||
|
||||
private String testSourceDirectory;
|
||||
|
||||
private final Map<String, String> properties = new TreeMap<>();
|
||||
|
||||
private final List<MavenPlugin> plugins = new ArrayList<>();
|
||||
|
||||
private String packaging;
|
||||
|
||||
public MavenBuild(BuildItemResolver buildItemResolver) {
|
||||
super(buildItemResolver);
|
||||
}
|
||||
|
||||
public MavenBuild() {
|
||||
this(null);
|
||||
}
|
||||
|
||||
public MavenParent parent(String groupId, String artifactId, String version) {
|
||||
this.parent = new MavenParent(groupId, artifactId, version);
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public MavenParent getParent() {
|
||||
return this.parent;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return this.description;
|
||||
}
|
||||
|
||||
public void setProperty(String key, String value) {
|
||||
this.properties.put(key, value);
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return Collections.unmodifiableMap(this.properties);
|
||||
}
|
||||
|
||||
public String getSourceDirectory() {
|
||||
return this.sourceDirectory;
|
||||
}
|
||||
|
||||
public void setSourceDirectory(String sourceDirectory) {
|
||||
this.sourceDirectory = sourceDirectory;
|
||||
}
|
||||
|
||||
public String getTestSourceDirectory() {
|
||||
return this.testSourceDirectory;
|
||||
}
|
||||
|
||||
public void setTestSourceDirectory(String testSourceDirectory) {
|
||||
this.testSourceDirectory = testSourceDirectory;
|
||||
}
|
||||
|
||||
public MavenPlugin plugin(String groupId, String artifactId) {
|
||||
MavenPlugin plugin = new MavenPlugin(groupId, artifactId);
|
||||
this.plugins.add(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public MavenPlugin plugin(String groupId, String artifactId, String version) {
|
||||
MavenPlugin plugin = new MavenPlugin(groupId, artifactId, version);
|
||||
this.plugins.add(plugin);
|
||||
return plugin;
|
||||
}
|
||||
|
||||
public List<MavenPlugin> getPlugins() {
|
||||
return Collections.unmodifiableList(this.plugins);
|
||||
}
|
||||
|
||||
public void setPackaging(String packaging) {
|
||||
this.packaging = packaging;
|
||||
}
|
||||
|
||||
public String getPackaging() {
|
||||
return this.packaging;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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 io.spring.initializr.generator.buildsystem.BuildSystem;
|
||||
|
||||
/**
|
||||
* Maven {@link BuildSystem}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public final class MavenBuildSystem implements BuildSystem {
|
||||
|
||||
/**
|
||||
* Maven {@link BuildSystem} identifier.
|
||||
*/
|
||||
public static final String ID = "maven";
|
||||
|
||||
@Override
|
||||
public String id() {
|
||||
return ID;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return id();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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 io.spring.initializr.generator.buildsystem.BuildSystemFactory;
|
||||
|
||||
/**
|
||||
* {@link BuildSystemFactory Factory} for {@link MavenBuildSystem}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
class MavenBuildSystemFactory implements BuildSystemFactory {
|
||||
|
||||
@Override
|
||||
public MavenBuildSystem createBuildSystem(String id) {
|
||||
if (MavenBuildSystem.ID.equals(id)) {
|
||||
return new MavenBuildSystem();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,371 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.BillOfMaterials;
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
import io.spring.initializr.generator.buildsystem.DependencyComparator;
|
||||
import io.spring.initializr.generator.buildsystem.DependencyContainer;
|
||||
import io.spring.initializr.generator.buildsystem.DependencyScope;
|
||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin.Configuration;
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin.Execution;
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenPlugin.Setting;
|
||||
import io.spring.initializr.generator.io.IndentingWriter;
|
||||
import io.spring.initializr.generator.version.VersionReference;
|
||||
|
||||
/**
|
||||
* A {@link MavenBuild} writer.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
public class MavenBuildWriter {
|
||||
|
||||
public void writeTo(IndentingWriter writer, MavenBuild build) throws IOException {
|
||||
writeProject(writer, () -> {
|
||||
writeParent(writer, build);
|
||||
writeProjectCoordinates(writer, build);
|
||||
writePackaging(writer, build);
|
||||
writeProjectName(writer, build);
|
||||
writeProperties(writer, build);
|
||||
writeDependencies(writer, build);
|
||||
writeDependencyManagement(writer, build);
|
||||
writeBuild(writer, build);
|
||||
writeRepositories(writer, build);
|
||||
});
|
||||
}
|
||||
|
||||
private void writeProject(IndentingWriter writer, Runnable whenWritten) {
|
||||
writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||
writer.println(
|
||||
"<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"");
|
||||
writer.indented(() -> {
|
||||
writer.println(
|
||||
"xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">");
|
||||
writeSingleElement(writer, "modelVersion", "4.0.0");
|
||||
whenWritten.run();
|
||||
});
|
||||
writer.println();
|
||||
writer.println("</project>");
|
||||
}
|
||||
|
||||
private void writeParent(IndentingWriter writer, MavenBuild build) {
|
||||
MavenParent parent = build.getParent();
|
||||
if (parent == null) {
|
||||
return;
|
||||
}
|
||||
writer.println("<parent>");
|
||||
writer.indented(() -> {
|
||||
writeSingleElement(writer, "groupId", parent.getGroupId());
|
||||
writeSingleElement(writer, "artifactId", parent.getArtifactId());
|
||||
writeSingleElement(writer, "version", parent.getVersion());
|
||||
writer.println("<relativePath/> <!-- lookup parent from repository -->");
|
||||
});
|
||||
writer.println("</parent>");
|
||||
}
|
||||
|
||||
private void writeProjectCoordinates(IndentingWriter writer, MavenBuild build) {
|
||||
writeSingleElement(writer, "groupId", build.getGroup());
|
||||
writeSingleElement(writer, "artifactId", build.getArtifact());
|
||||
writeSingleElement(writer, "version", build.getVersion());
|
||||
}
|
||||
|
||||
private void writePackaging(IndentingWriter writer, MavenBuild build) {
|
||||
String packaging = build.getPackaging();
|
||||
if (!"jar".equals(packaging)) {
|
||||
writeSingleElement(writer, "packaging", packaging);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeProjectName(IndentingWriter writer, MavenBuild build) {
|
||||
writeSingleElement(writer, "name", build.getName());
|
||||
writeSingleElement(writer, "description", build.getDescription());
|
||||
}
|
||||
|
||||
private void writeProperties(IndentingWriter writer, MavenBuild build) {
|
||||
if (build.getProperties().isEmpty() && build.getVersionProperties().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println();
|
||||
writeElement(writer, "properties", () -> {
|
||||
build.getProperties()
|
||||
.forEach((key, value) -> writeSingleElement(writer, key, value));
|
||||
build.getVersionProperties().forEach((key,
|
||||
value) -> writeSingleElement(writer, key.toStandardFormat(), value));
|
||||
});
|
||||
}
|
||||
|
||||
private void writeDependencies(IndentingWriter writer, MavenBuild build) {
|
||||
if (build.dependencies().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
DependencyContainer dependencies = build.dependencies();
|
||||
writer.println();
|
||||
writeElement(writer, "dependencies", () -> {
|
||||
Collection<Dependency> compiledDependencies = writeDependencies(writer,
|
||||
dependencies, DependencyScope.COMPILE);
|
||||
if (!compiledDependencies.isEmpty()) {
|
||||
writer.println();
|
||||
}
|
||||
writeDependencies(writer, dependencies, DependencyScope.RUNTIME);
|
||||
writeDependencies(writer, dependencies, DependencyScope.COMPILE_ONLY);
|
||||
writeDependencies(writer, dependencies, DependencyScope.ANNOTATION_PROCESSOR);
|
||||
writeDependencies(writer, dependencies, DependencyScope.PROVIDED_RUNTIME);
|
||||
writeDependencies(writer, dependencies, DependencyScope.TEST_COMPILE,
|
||||
DependencyScope.TEST_RUNTIME);
|
||||
});
|
||||
}
|
||||
|
||||
private Collection<Dependency> writeDependencies(IndentingWriter writer,
|
||||
DependencyContainer dependencies, DependencyScope... types) {
|
||||
Collection<Dependency> candidates = filterDependencies(dependencies, types);
|
||||
writeCollection(writer, candidates, this::writeDependency);
|
||||
return candidates;
|
||||
}
|
||||
|
||||
private void writeDependency(IndentingWriter writer, Dependency dependency) {
|
||||
writeElement(writer, "dependency", () -> {
|
||||
writeSingleElement(writer, "groupId", dependency.getGroupId());
|
||||
writeSingleElement(writer, "artifactId", dependency.getArtifactId());
|
||||
writeSingleElement(writer, "version",
|
||||
determineVersion(dependency.getVersion()));
|
||||
writeSingleElement(writer, "scope", scopeForType(dependency.getScope()));
|
||||
if (isOptional(dependency.getScope())) {
|
||||
writeSingleElement(writer, "optional", Boolean.toString(true));
|
||||
}
|
||||
writeSingleElement(writer, "type", dependency.getType());
|
||||
});
|
||||
}
|
||||
|
||||
private static Collection<Dependency> filterDependencies(
|
||||
DependencyContainer dependencies, DependencyScope... scopes) {
|
||||
List<DependencyScope> candidates = Arrays.asList(scopes);
|
||||
return dependencies.items().filter((dep) -> candidates.contains(dep.getScope()))
|
||||
.sorted(DependencyComparator.INSTANCE).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String scopeForType(DependencyScope type) {
|
||||
switch (type) {
|
||||
case ANNOTATION_PROCESSOR:
|
||||
return null;
|
||||
case COMPILE:
|
||||
return null;
|
||||
case COMPILE_ONLY:
|
||||
return null;
|
||||
case PROVIDED_RUNTIME:
|
||||
return "provided";
|
||||
case RUNTIME:
|
||||
return "runtime";
|
||||
case TEST_COMPILE:
|
||||
return "test";
|
||||
case TEST_RUNTIME:
|
||||
return "test";
|
||||
default:
|
||||
throw new IllegalStateException(
|
||||
"Unrecognized dependency type '" + type + "'");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOptional(DependencyScope type) {
|
||||
return (type == DependencyScope.ANNOTATION_PROCESSOR
|
||||
|| type == DependencyScope.COMPILE_ONLY);
|
||||
}
|
||||
|
||||
private void writeDependencyManagement(IndentingWriter writer, MavenBuild build) {
|
||||
if (build.boms().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<BillOfMaterials> boms = build.boms().items()
|
||||
.sorted(Comparator.comparing(BillOfMaterials::getOrder))
|
||||
.collect(Collectors.toList());
|
||||
writer.println();
|
||||
writeElement(writer, "dependencyManagement", () -> writeElement(writer,
|
||||
"dependencies", () -> writeCollection(writer, boms, this::writeBom)));
|
||||
}
|
||||
|
||||
private void writeBom(IndentingWriter writer, BillOfMaterials bom) {
|
||||
writeElement(writer, "dependency", () -> {
|
||||
writeSingleElement(writer, "groupId", bom.getGroupId());
|
||||
writeSingleElement(writer, "artifactId", bom.getArtifactId());
|
||||
writeSingleElement(writer, "version", determineVersion(bom.getVersion()));
|
||||
writeSingleElement(writer, "type", "pom");
|
||||
writeSingleElement(writer, "scope", "import");
|
||||
});
|
||||
}
|
||||
|
||||
private String determineVersion(VersionReference versionReference) {
|
||||
if (versionReference == null) {
|
||||
return null;
|
||||
}
|
||||
return (versionReference.isProperty())
|
||||
? "${" + versionReference.getProperty().toStandardFormat() + "}"
|
||||
: versionReference.getValue();
|
||||
}
|
||||
|
||||
private void writeBuild(IndentingWriter writer, MavenBuild build) {
|
||||
if (build.getSourceDirectory() == null && build.getTestSourceDirectory() == null
|
||||
&& build.getPlugins().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println();
|
||||
writeElement(writer, "build", () -> {
|
||||
writeSingleElement(writer, "sourceDirectory", build.getSourceDirectory());
|
||||
writeSingleElement(writer, "testSourceDirectory",
|
||||
build.getTestSourceDirectory());
|
||||
writePlugins(writer, build);
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void writePlugins(IndentingWriter writer, MavenBuild build) {
|
||||
if (build.getPlugins().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writeElement(writer, "plugins",
|
||||
() -> writeCollection(writer, build.getPlugins(), this::writePlugin));
|
||||
}
|
||||
|
||||
private void writePlugin(IndentingWriter writer, MavenPlugin plugin) {
|
||||
writeElement(writer, "plugin", () -> {
|
||||
writeSingleElement(writer, "groupId", plugin.getGroupId());
|
||||
writeSingleElement(writer, "artifactId", plugin.getArtifactId());
|
||||
writeSingleElement(writer, "version", plugin.getVersion());
|
||||
writePluginConfiguration(writer, plugin.getConfiguration());
|
||||
if (!plugin.getExecutions().isEmpty()) {
|
||||
writeElement(writer, "executions", () -> writeCollection(writer,
|
||||
plugin.getExecutions(), this::writePluginExecution));
|
||||
}
|
||||
if (!plugin.getDependencies().isEmpty()) {
|
||||
writeElement(writer, "dependencies", () -> writeCollection(writer,
|
||||
plugin.getDependencies(), this::writePluginDependency));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void writePluginConfiguration(IndentingWriter writer,
|
||||
Configuration configuration) {
|
||||
if (configuration == null || configuration.getSettings().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writeElement(writer, "configuration", () -> writeCollection(writer,
|
||||
configuration.getSettings(), this::writeSetting));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private void writeSetting(IndentingWriter writer, Setting setting) {
|
||||
if (setting.getValue() instanceof String) {
|
||||
writeSingleElement(writer, setting.getName(), (String) setting.getValue());
|
||||
}
|
||||
else if (setting.getValue() instanceof List) {
|
||||
writeElement(writer, setting.getName(), () -> writeCollection(writer,
|
||||
(List<Setting>) setting.getValue(), this::writeSetting));
|
||||
}
|
||||
}
|
||||
|
||||
private void writePluginExecution(IndentingWriter writer, Execution execution) {
|
||||
writeElement(writer, "execution", () -> {
|
||||
writeSingleElement(writer, "id", execution.getId());
|
||||
writeSingleElement(writer, "phase", execution.getPhase());
|
||||
List<String> goals = execution.getGoals();
|
||||
if (!goals.isEmpty()) {
|
||||
writeElement(writer, "goals", () -> goals
|
||||
.forEach((goal) -> writeSingleElement(writer, "goal", goal)));
|
||||
}
|
||||
writePluginConfiguration(writer, execution.getConfiguration());
|
||||
});
|
||||
}
|
||||
|
||||
private void writePluginDependency(IndentingWriter writer,
|
||||
MavenPlugin.Dependency dependency) {
|
||||
writeElement(writer, "dependency", () -> {
|
||||
writeSingleElement(writer, "groupId", dependency.getGroupId());
|
||||
writeSingleElement(writer, "artifactId", dependency.getArtifactId());
|
||||
writeSingleElement(writer, "version", dependency.getVersion());
|
||||
});
|
||||
}
|
||||
|
||||
private void writeRepositories(IndentingWriter writer, MavenBuild build) {
|
||||
List<MavenRepository> repositories = filterRepositories(
|
||||
build.repositories().items());
|
||||
List<MavenRepository> pluginRepositories = filterRepositories(
|
||||
build.pluginRepositories().items());
|
||||
if (repositories.isEmpty() && pluginRepositories.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println();
|
||||
if (!repositories.isEmpty()) {
|
||||
writeRepositories(writer, "repositories", "repository", repositories);
|
||||
}
|
||||
if (!pluginRepositories.isEmpty()) {
|
||||
writeRepositories(writer, "pluginRepositories", "pluginRepository",
|
||||
pluginRepositories);
|
||||
}
|
||||
}
|
||||
|
||||
private List<MavenRepository> filterRepositories(
|
||||
Stream<MavenRepository> repositories) {
|
||||
return repositories
|
||||
.filter((repository) -> !MavenRepository.MAVEN_CENTRAL.equals(repository))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private void writeRepositories(IndentingWriter writer, String containerName,
|
||||
String childName, List<MavenRepository> repositories) {
|
||||
writeElement(writer, containerName, () -> repositories
|
||||
.forEach((repository) -> writeElement(writer, childName, () -> {
|
||||
writeSingleElement(writer, "id", repository.getId());
|
||||
writeSingleElement(writer, "name", repository.getName());
|
||||
writeSingleElement(writer, "url", repository.getUrl());
|
||||
if (repository.isSnapshotsEnabled()) {
|
||||
writeElement(writer, "snapshots", () -> writeSingleElement(writer,
|
||||
"enabled", Boolean.toString(true)));
|
||||
}
|
||||
})));
|
||||
}
|
||||
|
||||
private void writeSingleElement(IndentingWriter writer, String name, String text) {
|
||||
if (text != null) {
|
||||
writer.print(String.format("<%s>", name));
|
||||
writer.print(text);
|
||||
writer.println(String.format("</%s>", name));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeElement(IndentingWriter writer, String name, Runnable withContent) {
|
||||
writer.println(String.format("<%s>", name));
|
||||
writer.indented(withContent);
|
||||
writer.println(String.format("</%s>", name));
|
||||
}
|
||||
|
||||
private <T> void writeCollection(IndentingWriter writer, Collection<T> collection,
|
||||
BiConsumer<IndentingWriter, T> itemWriter) {
|
||||
if (!collection.isEmpty()) {
|
||||
collection.forEach((item) -> itemWriter.accept(writer, item));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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;
|
||||
|
||||
/**
|
||||
* The {@code <parent>} in a Maven pom.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class MavenParent {
|
||||
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
MavenParent(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return this.artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,274 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
/**
|
||||
* A plugin in a {@link MavenBuild}.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class MavenPlugin {
|
||||
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
private final List<Execution> executions = new ArrayList<>();
|
||||
|
||||
private final List<Dependency> dependencies = new ArrayList<>();
|
||||
|
||||
private ConfigurationCustomization configurationCustomization = null;
|
||||
|
||||
public MavenPlugin(String groupId, String artifactId) {
|
||||
this(groupId, artifactId, null);
|
||||
}
|
||||
|
||||
public MavenPlugin(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return this.artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
public void configuration(Consumer<ConfigurationCustomization> consumer) {
|
||||
if (this.configurationCustomization == null) {
|
||||
this.configurationCustomization = new ConfigurationCustomization();
|
||||
}
|
||||
consumer.accept(this.configurationCustomization);
|
||||
}
|
||||
|
||||
public void execution(String id, Consumer<ExecutionBuilder> customizer) {
|
||||
ExecutionBuilder builder = new ExecutionBuilder(id);
|
||||
customizer.accept(builder);
|
||||
this.executions.add(builder.build());
|
||||
}
|
||||
|
||||
public List<Execution> getExecutions() {
|
||||
return this.executions;
|
||||
}
|
||||
|
||||
public void dependency(String groupId, String artifactId, String version) {
|
||||
this.dependencies.add(new Dependency(groupId, artifactId, version));
|
||||
}
|
||||
|
||||
public List<Dependency> getDependencies() {
|
||||
return Collections.unmodifiableList(this.dependencies);
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return (this.configurationCustomization == null) ? null
|
||||
: this.configurationCustomization.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for creation an {@link Execution}.
|
||||
*/
|
||||
public static class ExecutionBuilder {
|
||||
|
||||
private final String id;
|
||||
|
||||
private String phase;
|
||||
|
||||
private List<String> goals = new ArrayList<>();
|
||||
|
||||
private ConfigurationCustomization configurationCustomization = null;
|
||||
|
||||
public ExecutionBuilder(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
Execution build() {
|
||||
return new Execution(this.id, this.phase, this.goals,
|
||||
(this.configurationCustomization == null) ? null
|
||||
: this.configurationCustomization.build());
|
||||
}
|
||||
|
||||
public ExecutionBuilder phase(String phase) {
|
||||
this.phase = phase;
|
||||
return this;
|
||||
}
|
||||
|
||||
public ExecutionBuilder goal(String goal) {
|
||||
this.goals.add(goal);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void configuration(Consumer<ConfigurationCustomization> consumer) {
|
||||
if (this.configurationCustomization == null) {
|
||||
this.configurationCustomization = new ConfigurationCustomization();
|
||||
}
|
||||
consumer.accept(this.configurationCustomization);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Customization of a {@link Configuration}.
|
||||
*/
|
||||
public static class ConfigurationCustomization {
|
||||
|
||||
private final List<Setting> settings = new ArrayList<>();
|
||||
|
||||
public ConfigurationCustomization add(String key, String value) {
|
||||
this.settings.add(new Setting(key, value));
|
||||
return this;
|
||||
}
|
||||
|
||||
public ConfigurationCustomization add(String key,
|
||||
Consumer<ConfigurationCustomization> consumer) {
|
||||
ConfigurationCustomization nestedConfiguration = new ConfigurationCustomization();
|
||||
consumer.accept(nestedConfiguration);
|
||||
this.settings.add(new Setting(key, nestedConfiguration.settings));
|
||||
return this;
|
||||
}
|
||||
|
||||
Configuration build() {
|
||||
return new Configuration(this.settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code <configuration>} on an {@link Execution} or {@link MavenPlugin}.
|
||||
*/
|
||||
public static final class Configuration {
|
||||
|
||||
private final List<Setting> settings;
|
||||
|
||||
private Configuration(List<Setting> settings) {
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public List<Setting> getSettings() {
|
||||
return Collections.unmodifiableList(this.settings);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A setting in a {@link Configuration}.
|
||||
*/
|
||||
public static final class Setting {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final Object value;
|
||||
|
||||
private Setting(String name, Object value) {
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* An {@code <execution>} of a {@link MavenPlugin}.
|
||||
*/
|
||||
public static final class Execution {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String phase;
|
||||
|
||||
private final List<String> goals;
|
||||
|
||||
private final Configuration configuration;
|
||||
|
||||
private Execution(String id, String phase, List<String> goals,
|
||||
Configuration configuration) {
|
||||
this.id = id;
|
||||
this.phase = phase;
|
||||
this.goals = goals;
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
public String getPhase() {
|
||||
return this.phase;
|
||||
}
|
||||
|
||||
public List<String> getGoals() {
|
||||
return this.goals;
|
||||
}
|
||||
|
||||
public Configuration getConfiguration() {
|
||||
return this.configuration;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A {@code <dependency>} of a {@link MavenPlugin}.
|
||||
*/
|
||||
public static final class Dependency {
|
||||
|
||||
private final String groupId;
|
||||
|
||||
private final String artifactId;
|
||||
|
||||
private final String version;
|
||||
|
||||
private Dependency(String groupId, String artifactId, String version) {
|
||||
this.groupId = groupId;
|
||||
this.artifactId = artifactId;
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return this.groupId;
|
||||
}
|
||||
|
||||
public String getArtifactId() {
|
||||
return this.artifactId;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return this.version;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Maven build system. Provides a {@link io.spring.initializr.generator.buildsystem.Build
|
||||
* Build} abstraction and a writer for {@code pom.xml}.
|
||||
*/
|
||||
package io.spring.initializr.generator.buildsystem.maven;
|
@ -1,5 +1,6 @@
|
||||
io.spring.initializr.generator.buildsystem.BuildSystemFactory=\
|
||||
io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystemFactory
|
||||
io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystemFactory,\
|
||||
io.spring.initializr.generator.buildsystem.maven.MavenBuildSystemFactory
|
||||
|
||||
io.spring.initializr.generator.language.LanguageFactory=\
|
||||
io.spring.initializr.generator.language.groovy.GroovyLanguageFactory,\
|
||||
|
@ -19,6 +19,7 @@ package io.spring.initializr.generator.buildsystem;
|
||||
import java.nio.file.Path;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSystem;
|
||||
import io.spring.initializr.generator.buildsystem.maven.MavenBuildSystem;
|
||||
import io.spring.initializr.generator.language.java.JavaLanguage;
|
||||
import io.spring.initializr.generator.language.kotlin.KotlinLanguage;
|
||||
import org.junit.jupiter.api.Test;
|
||||
@ -42,6 +43,14 @@ class BuildSystemTests {
|
||||
assertThat(gradle.toString()).isEqualTo("gradle");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mavenBuildSystem() {
|
||||
BuildSystem maven = BuildSystem.forId("maven");
|
||||
assertThat(maven).isInstanceOf(MavenBuildSystem.class);
|
||||
assertThat(maven.id()).isEqualTo("maven");
|
||||
assertThat(maven.toString()).isEqualTo("maven");
|
||||
}
|
||||
|
||||
@Test
|
||||
void defaultMainDirectory(@TempDir Path directory) {
|
||||
Path mainDirectory = BuildSystem.forId("gradle").getMainDirectory(directory,
|
||||
|
@ -0,0 +1,534 @@
|
||||
/*
|
||||
* Copyright 2012-2019 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
|
||||
*
|
||||
* http://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.io.StringWriter;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.DependencyScope;
|
||||
import io.spring.initializr.generator.io.IndentingWriter;
|
||||
import io.spring.initializr.generator.test.assertj.NodeAssert;
|
||||
import io.spring.initializr.generator.version.VersionProperty;
|
||||
import io.spring.initializr.generator.version.VersionReference;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MavenBuildWriter}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class MavenBuildWriterTests {
|
||||
|
||||
@Test
|
||||
void basicPom() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/modelVersion").isEqualTo("4.0.0");
|
||||
assertThat(pom).textAtPath("/project/groupId").isEqualTo("com.example.demo");
|
||||
assertThat(pom).textAtPath("/project/artifactId").isEqualTo("demo");
|
||||
assertThat(pom).textAtPath("/project/version").isEqualTo("0.0.1-SNAPSHOT");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithNameAndDescription() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.setName("demo project");
|
||||
build.setDescription("A demo project");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/modelVersion").isEqualTo("4.0.0");
|
||||
assertThat(pom).textAtPath("/project/groupId").isEqualTo("com.example.demo");
|
||||
assertThat(pom).textAtPath("/project/artifactId").isEqualTo("demo");
|
||||
assertThat(pom).textAtPath("/project/version").isEqualTo("0.0.1-SNAPSHOT");
|
||||
assertThat(pom).textAtPath("/project/name").isEqualTo("demo project");
|
||||
assertThat(pom).textAtPath("/project/description")
|
||||
.isEqualTo("A demo project");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithParent() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.parent("org.springframework.boot", "spring-boot-starter-parent",
|
||||
"2.1.0.RELEASE");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/parent/groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(pom).textAtPath("/project/parent/artifactId")
|
||||
.isEqualTo("spring-boot-starter-parent");
|
||||
assertThat(pom).textAtPath("/project/parent/version")
|
||||
.isEqualTo("2.1.0.RELEASE");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPackaging() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.setPackaging("war");
|
||||
generatePom(build, (pom) -> assertThat(pom).textAtPath("/project/packaging")
|
||||
.isEqualTo("war"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithProperties() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.setProperty("java.version", "1.8");
|
||||
build.setProperty("alpha", "a");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/properties/java.version")
|
||||
.isEqualTo("1.8");
|
||||
assertThat(pom).textAtPath("/project/properties/alpha").isEqualTo("a");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithVersionProperties() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.addVersionProperty(VersionProperty.of("version.property"), "1.2.3");
|
||||
build.addInternalVersionProperty("internal.property", "4.5.6");
|
||||
build.addExternalVersionProperty("external.property", "7.8.9");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/properties/version.property")
|
||||
.isEqualTo("1.2.3");
|
||||
assertThat(pom).textAtPath("/project/properties/internal.property")
|
||||
.isEqualTo("4.5.6");
|
||||
assertThat(pom).textAtPath("/project/properties/external.property")
|
||||
.isEqualTo("7.8.9");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithAnnotationProcessorDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("annotation-processor", "org.springframework.boot",
|
||||
"spring-boot-configuration-processor",
|
||||
DependencyScope.ANNOTATION_PROCESSOR);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-configuration-processor");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("optional").isEqualTo("true");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithCompileOnlyDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("foo-bar", "org.springframework.boot",
|
||||
"spring-boot-foo-bar", DependencyScope.COMPILE_ONLY);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-foo-bar");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("optional").isEqualTo("true");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithCompileDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("root", "org.springframework.boot",
|
||||
"spring-boot-starter", DependencyScope.COMPILE);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-starter");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("optional").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithRuntimeDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("hikari", "com.zaxxer", "HikariCP",
|
||||
DependencyScope.RUNTIME);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId").isEqualTo("com.zaxxer");
|
||||
assertThat(dependency).textAtPath("artifactId").isEqualTo("HikariCP");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isEqualTo("runtime");
|
||||
assertThat(dependency).textAtPath("optional").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithProvidedRuntimeDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("tomcat", "org.springframework.boot",
|
||||
"spring-boot-starter-tomcat", DependencyScope.PROVIDED_RUNTIME);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-starter-tomcat");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isEqualTo("provided");
|
||||
assertThat(dependency).textAtPath("optional").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithTestCompileDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("test", "org.springframework.boot",
|
||||
"spring-boot-starter-test", DependencyScope.TEST_COMPILE);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-starter-test");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isEqualTo("test");
|
||||
assertThat(dependency).textAtPath("optional").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithTestRuntimeDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("embed-mongo", "de.flapdoodle.embed",
|
||||
"de.flapdoodle.embed.mongo", DependencyScope.TEST_RUNTIME);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId").isEqualTo("de.flapdoodle.embed");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("de.flapdoodle.embed.mongo");
|
||||
assertThat(dependency).textAtPath("version").isNullOrEmpty();
|
||||
assertThat(dependency).textAtPath("scope").isEqualTo("test");
|
||||
assertThat(dependency).textAtPath("optional").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithNonNullArtifactTypeDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.dependencies().add("root", "org.springframework.boot",
|
||||
"spring-boot-starter", null, DependencyScope.COMPILE, "tar.gz");
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom.nodeAtPath("/project/dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("type").isEqualTo("tar.gz");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithBom() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.boms().add("test", "com.example", "my-project-dependencies",
|
||||
VersionReference.ofValue("1.0.0.RELEASE"));
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependency = pom
|
||||
.nodeAtPath("/project/dependencyManagement/dependencies/dependency");
|
||||
assertBom(dependency, "com.example", "my-project-dependencies",
|
||||
"1.0.0.RELEASE");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithOrderedBoms() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.boms().add("bom1", "com.example", "my-project-dependencies",
|
||||
VersionReference.ofValue("1.0.0.RELEASE"), 5);
|
||||
build.boms().add("bom2", "com.example", "root-dependencies",
|
||||
VersionReference.ofProperty("root.version"), 2);
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert dependencies = pom
|
||||
.nodeAtPath("/project/dependencyManagement/dependencies");
|
||||
NodeAssert firstBom = assertThat(dependencies).nodeAtPath("dependency[1]");
|
||||
assertBom(firstBom, "com.example", "root-dependencies", "${root.version}");
|
||||
NodeAssert secondBom = assertThat(dependencies).nodeAtPath("dependency[2]");
|
||||
assertBom(secondBom, "com.example", "my-project-dependencies",
|
||||
"1.0.0.RELEASE");
|
||||
});
|
||||
}
|
||||
|
||||
private void assertBom(NodeAssert firstBom, String groupId, String artifactId,
|
||||
String version) {
|
||||
assertThat(firstBom).textAtPath("groupId").isEqualTo(groupId);
|
||||
assertThat(firstBom).textAtPath("artifactId").isEqualTo(artifactId);
|
||||
|
||||
assertThat(firstBom).textAtPath("version").isEqualTo(version);
|
||||
assertThat(firstBom).textAtPath("type").isEqualTo("pom");
|
||||
assertThat(firstBom).textAtPath("scope").isEqualTo("import");
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPlugin() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.plugin("org.springframework.boot", "spring-boot-maven-plugin");
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert plugin = pom.nodeAtPath("/project/build/plugins/plugin");
|
||||
assertThat(plugin).textAtPath("groupId")
|
||||
.isEqualTo("org.springframework.boot");
|
||||
assertThat(plugin).textAtPath("artifactId")
|
||||
.isEqualTo("spring-boot-maven-plugin");
|
||||
assertThat(plugin).textAtPath("version").isNullOrEmpty();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPluginWithConfiguration() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
MavenPlugin kotlin = build.plugin("org.jetbrains.kotlin", "kotlin-maven-plugin");
|
||||
kotlin.configuration((configuration) -> {
|
||||
configuration.add("args", (args) -> args.add("arg", "-Xjsr305=strict"));
|
||||
configuration.add("compilerPlugins",
|
||||
(compilerPlugins) -> compilerPlugins.add("plugin", "spring"));
|
||||
});
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert plugin = pom.nodeAtPath("/project/build/plugins/plugin");
|
||||
assertThat(plugin).textAtPath("groupId").isEqualTo("org.jetbrains.kotlin");
|
||||
assertThat(plugin).textAtPath("artifactId").isEqualTo("kotlin-maven-plugin");
|
||||
assertThat(plugin).textAtPath("version").isNullOrEmpty();
|
||||
NodeAssert configuration = plugin.nodeAtPath("configuration");
|
||||
assertThat(configuration).textAtPath("args/arg").isEqualTo("-Xjsr305=strict");
|
||||
assertThat(configuration).textAtPath("compilerPlugins/plugin")
|
||||
.isEqualTo("spring");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPluginWithExecution() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
MavenPlugin asciidoctor = build.plugin("org.asciidoctor",
|
||||
"asciidoctor-maven-plugin", "1.5.3");
|
||||
asciidoctor.execution("generateProject-docs", (execution) -> {
|
||||
execution.goal("process-asciidoc");
|
||||
execution.phase("generateProject-resources");
|
||||
execution.configuration((configuration) -> {
|
||||
configuration.add("doctype", "book");
|
||||
configuration.add("backend", "html");
|
||||
});
|
||||
});
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert plugin = pom.nodeAtPath("/project/build/plugins/plugin");
|
||||
assertThat(plugin).textAtPath("groupId").isEqualTo("org.asciidoctor");
|
||||
assertThat(plugin).textAtPath("artifactId")
|
||||
.isEqualTo("asciidoctor-maven-plugin");
|
||||
assertThat(plugin).textAtPath("version").isEqualTo("1.5.3");
|
||||
NodeAssert execution = plugin.nodeAtPath("executions/execution");
|
||||
assertThat(execution).textAtPath("id").isEqualTo("generateProject-docs");
|
||||
assertThat(execution).textAtPath("goals/goal").isEqualTo("process-asciidoc");
|
||||
assertThat(execution).textAtPath("phase")
|
||||
.isEqualTo("generateProject-resources");
|
||||
NodeAssert configuration = execution.nodeAtPath("configuration");
|
||||
assertThat(configuration).textAtPath("doctype").isEqualTo("book");
|
||||
assertThat(configuration).textAtPath("backend").isEqualTo("html");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPluginWithDependency() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
MavenPlugin kotlin = build.plugin("org.jetbrains.kotlin", "kotlin-maven-plugin");
|
||||
kotlin.dependency("org.jetbrains.kotlin", "kotlin-maven-allopen",
|
||||
"${kotlin.version}");
|
||||
generatePom(build, (pom) -> {
|
||||
NodeAssert plugin = pom.nodeAtPath("/project/build/plugins/plugin");
|
||||
assertThat(plugin).textAtPath("groupId").isEqualTo("org.jetbrains.kotlin");
|
||||
assertThat(plugin).textAtPath("artifactId").isEqualTo("kotlin-maven-plugin");
|
||||
NodeAssert dependency = plugin.nodeAtPath("dependencies/dependency");
|
||||
assertThat(dependency).textAtPath("groupId")
|
||||
.isEqualTo("org.jetbrains.kotlin");
|
||||
assertThat(dependency).textAtPath("artifactId")
|
||||
.isEqualTo("kotlin-maven-allopen");
|
||||
assertThat(dependency).textAtPath("version").isEqualTo("${kotlin.version}");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithMavenCentral() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.repositories().add("maven-central");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).nodeAtPath("/project/repositories").isNull();
|
||||
assertThat(pom).nodeAtPath("/project/pluginRepositories").isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithRepository() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.repositories().add("spring-milestones", "Spring Milestones",
|
||||
"https://repo.spring.io/milestone");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/id")
|
||||
.isEqualTo("spring-milestones");
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/name")
|
||||
.isEqualTo("Spring Milestones");
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/url")
|
||||
.isEqualTo("https://repo.spring.io/milestone");
|
||||
assertThat(pom).nodeAtPath("/project/repositories/repository/snapshots")
|
||||
.isNull();
|
||||
assertThat(pom).nodeAtPath("/project/pluginRepositories").isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithPluginRepository() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.pluginRepositories().add("spring-milestones", "Spring Milestones",
|
||||
"https://repo.spring.io/milestone");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/pluginRepositories/pluginRepository/id")
|
||||
.isEqualTo("spring-milestones");
|
||||
assertThat(pom)
|
||||
.textAtPath("/project/pluginRepositories/pluginRepository/name")
|
||||
.isEqualTo("Spring Milestones");
|
||||
assertThat(pom).textAtPath("/project/pluginRepositories/pluginRepository/url")
|
||||
.isEqualTo("https://repo.spring.io/milestone");
|
||||
assertThat(pom).nodeAtPath("/project/repositories/repository/snapshots")
|
||||
.isNull();
|
||||
assertThat(pom).nodeAtPath("/project/repositories").isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithSnapshotRepository() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.repositories().add("spring-snapshots", "Spring Snapshots",
|
||||
"https://repo.spring.io/snapshot", true);
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/id")
|
||||
.isEqualTo("spring-snapshots");
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/name")
|
||||
.isEqualTo("Spring Snapshots");
|
||||
assertThat(pom).textAtPath("/project/repositories/repository/url")
|
||||
.isEqualTo("https://repo.spring.io/snapshot");
|
||||
assertThat(pom)
|
||||
.textAtPath("/project/repositories/repository/snapshots/enabled")
|
||||
.isEqualTo("true");
|
||||
assertThat(pom).nodeAtPath("/project/pluginRepositories").isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithSnapshotPluginRepository() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.pluginRepositories().add("spring-snapshots", "Spring Snapshots",
|
||||
"https://repo.spring.io/snapshot", true);
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/pluginRepositories/pluginRepository/id")
|
||||
.isEqualTo("spring-snapshots");
|
||||
assertThat(pom)
|
||||
.textAtPath("/project/pluginRepositories/pluginRepository/name")
|
||||
.isEqualTo("Spring Snapshots");
|
||||
assertThat(pom).textAtPath("/project/pluginRepositories/pluginRepository/url")
|
||||
.isEqualTo("https://repo.spring.io/snapshot");
|
||||
assertThat(pom).textAtPath(
|
||||
"/project/pluginRepositories/pluginRepository/snapshots/enabled")
|
||||
.isEqualTo("true");
|
||||
assertThat(pom).nodeAtPath("/project/repositories").isNull();
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithCustomSourceDirectories() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setGroup("com.example.demo");
|
||||
build.setArtifact("demo");
|
||||
build.setSourceDirectory("${project.basedir}/src/main/kotlin");
|
||||
build.setTestSourceDirectory("${project.basedir}/src/test/kotlin");
|
||||
generatePom(build, (pom) -> {
|
||||
assertThat(pom).textAtPath("/project/build/sourceDirectory")
|
||||
.isEqualTo("${project.basedir}/src/main/kotlin");
|
||||
assertThat(pom).textAtPath("/project/build/testSourceDirectory")
|
||||
.isEqualTo("${project.basedir}/src/test/kotlin");
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void pomWithCustomVersion() throws Exception {
|
||||
MavenBuild build = new MavenBuild();
|
||||
build.setVersion("1.2.4.RELEASE");
|
||||
generatePom(build, (pom) -> assertThat(pom).textAtPath("/project/version")
|
||||
.isEqualTo("1.2.4.RELEASE"));
|
||||
}
|
||||
|
||||
private void generatePom(MavenBuild mavenBuild, Consumer<NodeAssert> consumer)
|
||||
throws Exception {
|
||||
MavenBuildWriter writer = new MavenBuildWriter();
|
||||
StringWriter out = new StringWriter();
|
||||
writer.writeTo(new IndentingWriter(out), mavenBuild);
|
||||
consumer.accept(new NodeAssert(out.toString()));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
/*
|
||||
* Copyright 2012-2018 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
|
||||
*
|
||||
* http://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.test.assertj;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.xpath.XPath;
|
||||
import javax.xml.xpath.XPathConstants;
|
||||
import javax.xml.xpath.XPathExpressionException;
|
||||
import javax.xml.xpath.XPathFactory;
|
||||
|
||||
import org.assertj.core.api.AbstractAssert;
|
||||
import org.assertj.core.api.AssertProvider;
|
||||
import org.assertj.core.api.ListAssert;
|
||||
import org.assertj.core.api.StringAssert;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
/**
|
||||
* AssertJ {@link AssertProvider} for {@link Node} assertions.
|
||||
*
|
||||
* @author Andy Wilkinson
|
||||
*/
|
||||
public class NodeAssert extends AbstractAssert<NodeAssert, Node>
|
||||
implements AssertProvider<NodeAssert> {
|
||||
|
||||
private static final DocumentBuilderFactory FACTORY = DocumentBuilderFactory
|
||||
.newInstance();
|
||||
|
||||
private final XPathFactory xpathFactory = XPathFactory.newInstance();
|
||||
|
||||
private final XPath xpath = this.xpathFactory.newXPath();
|
||||
|
||||
public NodeAssert(Path xmlFile) {
|
||||
this(read(xmlFile));
|
||||
}
|
||||
|
||||
public NodeAssert(String xmlContent) {
|
||||
this(read(xmlContent));
|
||||
}
|
||||
|
||||
public NodeAssert(Node actual) {
|
||||
super(actual, NodeAssert.class);
|
||||
}
|
||||
|
||||
private static Document read(Path xmlFile) {
|
||||
try {
|
||||
return FACTORY.newDocumentBuilder().parse(xmlFile.toFile());
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static Document read(String xmlContent) {
|
||||
try {
|
||||
return FACTORY.newDocumentBuilder().parse(new ByteArrayInputStream(
|
||||
xmlContent.getBytes(StandardCharsets.UTF_8)));
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public NodeAssert nodeAtPath(String xpath) {
|
||||
try {
|
||||
return new NodeAssert(
|
||||
(Node) this.xpath.evaluate(xpath, this.actual, XPathConstants.NODE));
|
||||
}
|
||||
catch (XPathExpressionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public ListAssert<Node> nodesAtPath(String xpath) {
|
||||
try {
|
||||
NodeList nodeList = (NodeList) this.xpath.evaluate(xpath, this.actual,
|
||||
XPathConstants.NODESET);
|
||||
return new ListAssert<>(toList(nodeList));
|
||||
}
|
||||
catch (XPathExpressionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
public StringAssert textAtPath(String xpath) {
|
||||
try {
|
||||
return new StringAssert((String) this.xpath.evaluate(xpath + "/text()",
|
||||
this.actual, XPathConstants.STRING));
|
||||
}
|
||||
catch (XPathExpressionException ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public NodeAssert assertThat() {
|
||||
return this;
|
||||
}
|
||||
|
||||
private static List<Node> toList(NodeList nodeList) {
|
||||
List<Node> nodes = new ArrayList<>();
|
||||
for (int i = 0; i < nodeList.getLength(); i++) {
|
||||
nodes.add(nodeList.item(i));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user