mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-17 01:46:19 +08:00
Add Gradle plugin mapping strategy
This commit adds a mapping strategy for Gradle plugins that don't have a plugin marker artifact. This is necessary to avoid using a buildScript section to declare the plugin implementation artifact. Closes gh-1189
This commit is contained in:
parent
cac36a0d37
commit
d1df1d5241
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2012-2019 the original author or authors.
|
||||
* Copyright 2012-2021 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.
|
||||
@ -16,7 +16,11 @@
|
||||
|
||||
package io.spring.initializr.generator.buildsystem.gradle;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.BuildSettings;
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
|
||||
/**
|
||||
* Gradle-specific {@linkplain BuildSettings build settings}.
|
||||
@ -27,9 +31,12 @@ public class GradleBuildSettings extends BuildSettings {
|
||||
|
||||
private final String sourceCompatibility;
|
||||
|
||||
private final List<PluginMapping> pluginMappings;
|
||||
|
||||
protected GradleBuildSettings(Builder builder) {
|
||||
super(builder);
|
||||
this.sourceCompatibility = builder.sourceCompatibility;
|
||||
this.pluginMappings = new ArrayList<>(builder.pluginMappings);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,6 +47,14 @@ public class GradleBuildSettings extends BuildSettings {
|
||||
return this.sourceCompatibility;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the {@link PluginMapping plugin mappings}, if any.
|
||||
* @return the plugin mappings
|
||||
*/
|
||||
public List<PluginMapping> getPluginMappings() {
|
||||
return this.pluginMappings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builder for {@link GradleBuildSettings}.
|
||||
*/
|
||||
@ -47,6 +62,8 @@ public class GradleBuildSettings extends BuildSettings {
|
||||
|
||||
private String sourceCompatibility;
|
||||
|
||||
private final List<PluginMapping> pluginMappings = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Set the java version compatibility to use when compiling Java source.
|
||||
* @param sourceCompatibility java version compatibility
|
||||
@ -57,6 +74,21 @@ public class GradleBuildSettings extends BuildSettings {
|
||||
return self();
|
||||
}
|
||||
|
||||
/**
|
||||
* Map the plugin with the specified id to the specified {@link Dependency}. This
|
||||
* is mandatory when a plugin does not have an appropriate plugin marker artifact.
|
||||
* @param id the id of a plugin
|
||||
* @param pluginDependency the dependency for that plugin
|
||||
* @return this for method chaining
|
||||
*/
|
||||
public Builder mapPlugin(String id, Dependency pluginDependency) {
|
||||
if (pluginDependency.getVersion() == null || pluginDependency.getVersion().isProperty()) {
|
||||
throw new IllegalArgumentException("Mapping for plugin '" + id + "' must have a version");
|
||||
}
|
||||
this.pluginMappings.add(new PluginMapping(id, pluginDependency));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a {@link GradleBuildSettings} with the current state of this builder.
|
||||
* @return a {@link GradleBuildSettings}
|
||||
@ -67,4 +99,36 @@ public class GradleBuildSettings extends BuildSettings {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a plugin identifier to a plugin implementation artifact.
|
||||
*/
|
||||
public static class PluginMapping {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final Dependency dependency;
|
||||
|
||||
PluginMapping(String id, Dependency dependency) {
|
||||
this.id = id;
|
||||
this.dependency = dependency;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the id of the plugin.
|
||||
* @return the plugin id
|
||||
*/
|
||||
public String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the plugin implementation dependency.
|
||||
* @return the plugin implementation
|
||||
*/
|
||||
public Dependency getDependency() {
|
||||
return this.dependency;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -16,7 +16,9 @@
|
||||
|
||||
package io.spring.initializr.generator.buildsystem.gradle;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSettings.PluginMapping;
|
||||
import io.spring.initializr.generator.io.IndentingWriter;
|
||||
|
||||
/**
|
||||
@ -41,15 +43,21 @@ public abstract class GradleSettingsWriter {
|
||||
}
|
||||
|
||||
private void writePluginManagement(IndentingWriter writer, GradleBuild build) {
|
||||
if (build.pluginRepositories().isEmpty()) {
|
||||
if (build.pluginRepositories().isEmpty() && build.getSettings().getPluginMappings().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println("pluginManagement {");
|
||||
writer.indented(() -> writeRepositories(writer, build));
|
||||
writer.indented(() -> {
|
||||
writeRepositories(writer, build);
|
||||
writeResolutionStrategy(writer, build);
|
||||
});
|
||||
writer.println("}");
|
||||
}
|
||||
|
||||
private void writeRepositories(IndentingWriter writer, GradleBuild build) {
|
||||
if (build.pluginRepositories().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println("repositories {");
|
||||
writer.indented(() -> {
|
||||
build.pluginRepositories().items().map(this::repositoryAsString).forEach(writer::println);
|
||||
@ -58,6 +66,29 @@ public abstract class GradleSettingsWriter {
|
||||
writer.println("}");
|
||||
}
|
||||
|
||||
private void writeResolutionStrategy(IndentingWriter writer, GradleBuild build) {
|
||||
if (build.getSettings().getPluginMappings().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
writer.println("resolutionStrategy {");
|
||||
writer.indented(() -> {
|
||||
writer.println("eachPlugin {");
|
||||
writer.indented(() -> build.getSettings().getPluginMappings()
|
||||
.forEach((pluginMapping) -> writePluginMapping(writer, pluginMapping)));
|
||||
writer.println("}");
|
||||
});
|
||||
writer.println("}");
|
||||
}
|
||||
|
||||
private void writePluginMapping(IndentingWriter writer, PluginMapping pluginMapping) {
|
||||
writer.println("if (requested.id.id == " + wrapWithQuotes(pluginMapping.getId()) + ") {");
|
||||
Dependency dependency = pluginMapping.getDependency();
|
||||
String module = String.format("%s:%s:%s", dependency.getGroupId(), dependency.getArtifactId(),
|
||||
dependency.getVersion().getValue());
|
||||
writer.indented(() -> writer.println("useModule(" + wrapWithQuotes(module) + ")"));
|
||||
writer.println("}");
|
||||
}
|
||||
|
||||
private String repositoryAsString(MavenRepository repository) {
|
||||
if (MavenRepository.MAVEN_CENTRAL.equals(repository)) {
|
||||
return "mavenCentral()";
|
||||
|
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012-2021 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.gradle;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSettings.Builder;
|
||||
import io.spring.initializr.generator.version.VersionReference;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link GradleBuildSettings}.
|
||||
*
|
||||
* @author Stephane Nicoll
|
||||
*/
|
||||
class GradleBuildSettingsTests {
|
||||
|
||||
@Test
|
||||
void mapPluginWithoutVersionIsNotAllowed() {
|
||||
Builder settingsBuilder = new Builder();
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> settingsBuilder.mapPlugin("test", Dependency.withCoordinates("com.example", "plugin").build()))
|
||||
.withMessage("Mapping for plugin 'test' must have a version");
|
||||
}
|
||||
|
||||
@Test
|
||||
void mapPluginWithVersionReferenceIsNotAllowed() {
|
||||
Builder settingsBuilder = new Builder();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> settingsBuilder.mapPlugin("test",
|
||||
Dependency.withCoordinates("com.example", "plugin")
|
||||
.version(VersionReference.ofProperty("test.version")).build()))
|
||||
.withMessage("Mapping for plugin 'test' must have a version");
|
||||
}
|
||||
|
||||
@Test
|
||||
void settingsFromBuilderClonePluginMappings() {
|
||||
Builder settingsBuilder = new Builder();
|
||||
settingsBuilder.mapPlugin("test",
|
||||
Dependency.withCoordinates("com.example", "plugin").version(VersionReference.ofValue("1.0.0")).build());
|
||||
GradleBuildSettings firstSettings = settingsBuilder.build();
|
||||
settingsBuilder.mapPlugin("another", Dependency.withCoordinates("com.example", "another")
|
||||
.version(VersionReference.ofValue("2.0.0")).build());
|
||||
assertThat(firstSettings.getPluginMappings()).singleElement()
|
||||
.satisfies((pluginMapping) -> assertThat(pluginMapping.getId()).isEqualTo("test"));
|
||||
}
|
||||
|
||||
}
|
@ -20,8 +20,10 @@ import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||
import io.spring.initializr.generator.io.IndentingWriter;
|
||||
import io.spring.initializr.generator.version.VersionReference;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -73,6 +75,32 @@ class GroovyDslGradleSettingsWriterTests {
|
||||
"}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void gradleBuildWithPluginMappings() {
|
||||
GradleBuild build = new GradleBuild();
|
||||
build.settings()
|
||||
.mapPlugin("com.example",
|
||||
Dependency.withCoordinates("com.example", "gradle-plugin")
|
||||
.version(VersionReference.ofValue("1.0.0")).build())
|
||||
.mapPlugin("org.acme", Dependency.withCoordinates("org.acme.plugin", "gradle")
|
||||
.version(VersionReference.ofValue("2.0.0")).build());
|
||||
List<String> lines = generateSettings(build);
|
||||
assertThat(lines)
|
||||
.containsSequence(// @formatter:off
|
||||
"pluginManagement {",
|
||||
" resolutionStrategy {",
|
||||
" eachPlugin {",
|
||||
" if (requested.id.id == 'com.example') {",
|
||||
" useModule('com.example:gradle-plugin:1.0.0')",
|
||||
" }",
|
||||
" if (requested.id.id == 'org.acme') {",
|
||||
" useModule('org.acme.plugin:gradle:2.0.0')",
|
||||
" }",
|
||||
" }",
|
||||
" }",
|
||||
"}"); // @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
||||
GradleBuild build = new GradleBuild();
|
||||
|
@ -20,8 +20,10 @@ import java.io.StringWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||
import io.spring.initializr.generator.io.IndentingWriter;
|
||||
import io.spring.initializr.generator.version.VersionReference;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ -72,6 +74,32 @@ class KotlinDslGradleSettingsWriterTests {
|
||||
" }", "}");
|
||||
}
|
||||
|
||||
@Test
|
||||
void gradleBuildWithPluginMappings() {
|
||||
GradleBuild build = new GradleBuild();
|
||||
build.settings()
|
||||
.mapPlugin("com.example",
|
||||
Dependency.withCoordinates("com.example", "gradle-plugin")
|
||||
.version(VersionReference.ofValue("1.0.0")).build())
|
||||
.mapPlugin("org.acme", Dependency.withCoordinates("org.acme.plugin", "gradle")
|
||||
.version(VersionReference.ofValue("2.0.0")).build());
|
||||
List<String> lines = generateSettings(build);
|
||||
assertThat(lines)
|
||||
.containsSequence(// @formatter:off
|
||||
"pluginManagement {",
|
||||
" resolutionStrategy {",
|
||||
" eachPlugin {",
|
||||
" if (requested.id.id == \"com.example\") {",
|
||||
" useModule(\"com.example:gradle-plugin:1.0.0\")",
|
||||
" }",
|
||||
" if (requested.id.id == \"org.acme\") {",
|
||||
" useModule(\"org.acme.plugin:gradle:2.0.0\")",
|
||||
" }",
|
||||
" }",
|
||||
" }",
|
||||
"}"); // @formatter:on
|
||||
}
|
||||
|
||||
@Test
|
||||
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
||||
GradleBuild build = new GradleBuild();
|
||||
|
Loading…
Reference in New Issue
Block a user