mirror of
https://gitee.com/dcren/initializr.git
synced 2025-07-18 13:26:43 +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");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with 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;
|
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.BuildSettings;
|
||||||
|
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gradle-specific {@linkplain BuildSettings build settings}.
|
* Gradle-specific {@linkplain BuildSettings build settings}.
|
||||||
@ -27,9 +31,12 @@ public class GradleBuildSettings extends BuildSettings {
|
|||||||
|
|
||||||
private final String sourceCompatibility;
|
private final String sourceCompatibility;
|
||||||
|
|
||||||
|
private final List<PluginMapping> pluginMappings;
|
||||||
|
|
||||||
protected GradleBuildSettings(Builder builder) {
|
protected GradleBuildSettings(Builder builder) {
|
||||||
super(builder);
|
super(builder);
|
||||||
this.sourceCompatibility = builder.sourceCompatibility;
|
this.sourceCompatibility = builder.sourceCompatibility;
|
||||||
|
this.pluginMappings = new ArrayList<>(builder.pluginMappings);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,6 +47,14 @@ public class GradleBuildSettings extends BuildSettings {
|
|||||||
return this.sourceCompatibility;
|
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}.
|
* Builder for {@link GradleBuildSettings}.
|
||||||
*/
|
*/
|
||||||
@ -47,6 +62,8 @@ public class GradleBuildSettings extends BuildSettings {
|
|||||||
|
|
||||||
private String sourceCompatibility;
|
private String sourceCompatibility;
|
||||||
|
|
||||||
|
private final List<PluginMapping> pluginMappings = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the java version compatibility to use when compiling Java source.
|
* Set the java version compatibility to use when compiling Java source.
|
||||||
* @param sourceCompatibility java version compatibility
|
* @param sourceCompatibility java version compatibility
|
||||||
@ -57,6 +74,21 @@ public class GradleBuildSettings extends BuildSettings {
|
|||||||
return self();
|
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.
|
* Build a {@link GradleBuildSettings} with the current state of this builder.
|
||||||
* @return a {@link GradleBuildSettings}
|
* @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;
|
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.MavenRepository;
|
||||||
|
import io.spring.initializr.generator.buildsystem.gradle.GradleBuildSettings.PluginMapping;
|
||||||
import io.spring.initializr.generator.io.IndentingWriter;
|
import io.spring.initializr.generator.io.IndentingWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -41,15 +43,21 @@ public abstract class GradleSettingsWriter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void writePluginManagement(IndentingWriter writer, GradleBuild build) {
|
private void writePluginManagement(IndentingWriter writer, GradleBuild build) {
|
||||||
if (build.pluginRepositories().isEmpty()) {
|
if (build.pluginRepositories().isEmpty() && build.getSettings().getPluginMappings().isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
writer.println("pluginManagement {");
|
writer.println("pluginManagement {");
|
||||||
writer.indented(() -> writeRepositories(writer, build));
|
writer.indented(() -> {
|
||||||
|
writeRepositories(writer, build);
|
||||||
|
writeResolutionStrategy(writer, build);
|
||||||
|
});
|
||||||
writer.println("}");
|
writer.println("}");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeRepositories(IndentingWriter writer, GradleBuild build) {
|
private void writeRepositories(IndentingWriter writer, GradleBuild build) {
|
||||||
|
if (build.pluginRepositories().isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
writer.println("repositories {");
|
writer.println("repositories {");
|
||||||
writer.indented(() -> {
|
writer.indented(() -> {
|
||||||
build.pluginRepositories().items().map(this::repositoryAsString).forEach(writer::println);
|
build.pluginRepositories().items().map(this::repositoryAsString).forEach(writer::println);
|
||||||
@ -58,6 +66,29 @@ public abstract class GradleSettingsWriter {
|
|||||||
writer.println("}");
|
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) {
|
private String repositoryAsString(MavenRepository repository) {
|
||||||
if (MavenRepository.MAVEN_CENTRAL.equals(repository)) {
|
if (MavenRepository.MAVEN_CENTRAL.equals(repository)) {
|
||||||
return "mavenCentral()";
|
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.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||||
import io.spring.initializr.generator.io.IndentingWriter;
|
import io.spring.initializr.generator.io.IndentingWriter;
|
||||||
|
import io.spring.initializr.generator.version.VersionReference;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
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
|
@Test
|
||||||
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
||||||
GradleBuild build = new GradleBuild();
|
GradleBuild build = new GradleBuild();
|
||||||
|
@ -20,8 +20,10 @@ import java.io.StringWriter;
|
|||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import io.spring.initializr.generator.buildsystem.Dependency;
|
||||||
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
import io.spring.initializr.generator.buildsystem.MavenRepository;
|
||||||
import io.spring.initializr.generator.io.IndentingWriter;
|
import io.spring.initializr.generator.io.IndentingWriter;
|
||||||
|
import io.spring.initializr.generator.version.VersionReference;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
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
|
@Test
|
||||||
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
void artifactIdShouldBeUsedAsTheRootProjectName() {
|
||||||
GradleBuild build = new GradleBuild();
|
GradleBuild build = new GradleBuild();
|
||||||
|
Loading…
Reference in New Issue
Block a user