3 changed files with 333 additions and 243 deletions
@ -0,0 +1,209 @@
@@ -0,0 +1,209 @@
|
||||
/* |
||||
* Copyright 2012-2020 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 org.springframework.boot.build; |
||||
|
||||
import java.io.File; |
||||
import java.io.IOException; |
||||
import java.io.InputStream; |
||||
import java.io.InputStreamReader; |
||||
import java.net.URISyntaxException; |
||||
import java.net.URL; |
||||
import java.nio.charset.StandardCharsets; |
||||
import java.util.List; |
||||
import java.util.Map; |
||||
import java.util.TreeMap; |
||||
import java.util.function.Consumer; |
||||
|
||||
import io.spring.javaformat.gradle.FormatTask; |
||||
import io.spring.javaformat.gradle.SpringJavaFormatPlugin; |
||||
import org.gradle.api.GradleException; |
||||
import org.gradle.api.Project; |
||||
import org.gradle.api.artifacts.DependencySet; |
||||
import org.gradle.api.file.CopySpec; |
||||
import org.gradle.api.plugins.JavaBasePlugin; |
||||
import org.gradle.api.plugins.quality.CheckstyleExtension; |
||||
import org.gradle.api.plugins.quality.CheckstylePlugin; |
||||
import org.gradle.api.resources.TextResourceFactory; |
||||
import org.gradle.api.tasks.bundling.Jar; |
||||
import org.gradle.api.tasks.compile.JavaCompile; |
||||
import org.gradle.api.tasks.javadoc.Javadoc; |
||||
import org.gradle.api.tasks.testing.Test; |
||||
import org.gradle.testretry.TestRetryPlugin; |
||||
import org.gradle.testretry.TestRetryTaskExtension; |
||||
|
||||
import org.springframework.boot.build.testing.TestFailuresPlugin; |
||||
import org.springframework.util.FileCopyUtils; |
||||
|
||||
/** |
||||
* Applies Java Plugin conventions to projects that are part of Spring Boot's build. |
||||
* Conventions are applied in response to various plugins being applied. |
||||
* <p/> |
||||
* |
||||
* When the {@link JavaBasePlugin Java base plugin} is applied: |
||||
* |
||||
* <p/> |
||||
* |
||||
* <ul> |
||||
* <li>{@code sourceCompatibility} is set to {@code 1.8} |
||||
* <li>{@link SpringJavaFormatPlugin Spring Java Format}, {@link CheckstylePlugin |
||||
* Checkstyle}, {@link TestFailuresPlugin Test Failures}, and {@link TestRetryPlugin Test |
||||
* Retry} plugins are applied |
||||
* <li>{@link Test} tasks are configured to use JUnit Platform and use a max heap of 1024M |
||||
* <li>{@link JavaCompile}, {@link Javadoc}, and {@link FormatTask} tasks are configured |
||||
* to use UTF-8 encoding |
||||
* <li>{@link JavaCompile} tasks are configured to use {@code -parameters} |
||||
* <li>{@link Jar} tasks are configured to produce jars with LICENSE.txt and NOTICE.txt |
||||
* files and the following manifest entries: |
||||
* <ul> |
||||
* <li>{@code Automatic-Module-Name} |
||||
* <li>{@code Build-Jdk-Spec} |
||||
* <li>{@code Built-By} |
||||
* <li>{@code Implementation-Title} |
||||
* <li>{@code Implementation-Version} |
||||
* </ul> |
||||
* </ul> |
||||
* |
||||
* <p/> |
||||
* |
||||
* @author Andy Wilkinson |
||||
* @author Christoph Dreis |
||||
* @author Mike Smithson |
||||
*/ |
||||
class JavaConventions { |
||||
|
||||
void apply(Project project) { |
||||
project.getPlugins().withType(JavaBasePlugin.class, (java) -> { |
||||
project.getPlugins().apply(TestFailuresPlugin.class); |
||||
configureSpringJavaFormat(project); |
||||
project.setProperty("sourceCompatibility", "1.8"); |
||||
configureJavaCompileConventions(project); |
||||
configureJavadocConventions(project); |
||||
configureTestConventions(project); |
||||
configureJarManifestConventions(project); |
||||
}); |
||||
} |
||||
|
||||
private void configureJarManifestConventions(Project project) { |
||||
project.getTasks().withType(Jar.class, (jar) -> project.afterEvaluate((evaluated) -> { |
||||
jar.metaInf((metaInf) -> copyLegalFiles(project, metaInf)); |
||||
jar.manifest((manifest) -> { |
||||
Map<String, Object> attributes = new TreeMap<>(); |
||||
attributes.put("Automatic-Module-Name", project.getName().replace("-", ".")); |
||||
attributes.put("Build-Jdk-Spec", project.property("sourceCompatibility")); |
||||
attributes.put("Built-By", "Spring"); |
||||
attributes.put("Implementation-Title", project.getDescription()); |
||||
attributes.put("Implementation-Version", project.getVersion()); |
||||
manifest.attributes(attributes); |
||||
}); |
||||
})); |
||||
} |
||||
|
||||
private void configureTestConventions(Project project) { |
||||
project.getPlugins().apply(TestRetryPlugin.class); |
||||
project.getTasks().withType(Test.class, (test) -> { |
||||
withOptionalBuildJavaHome(project, (javaHome) -> test.setExecutable(javaHome + "/bin/java")); |
||||
test.useJUnitPlatform(); |
||||
test.setMaxHeapSize("1024M"); |
||||
project.getPlugins().withType(TestRetryPlugin.class, (testRetryPlugin) -> { |
||||
TestRetryTaskExtension testRetry = test.getExtensions().getByType(TestRetryTaskExtension.class); |
||||
testRetry.getFailOnPassedAfterRetry().set(true); |
||||
testRetry.getMaxRetries().set(3); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
private void configureJavadocConventions(Project project) { |
||||
project.getTasks().withType(Javadoc.class, (javadoc) -> { |
||||
javadoc.getOptions().source("1.8").encoding("UTF-8"); |
||||
withOptionalBuildJavaHome(project, (javaHome) -> javadoc.setExecutable(javaHome + "/bin/javadoc")); |
||||
}); |
||||
} |
||||
|
||||
private void configureJavaCompileConventions(Project project) { |
||||
project.getTasks().withType(JavaCompile.class, (compile) -> { |
||||
compile.getOptions().setEncoding("UTF-8"); |
||||
withOptionalBuildJavaHome(project, (javaHome) -> { |
||||
compile.getOptions().setFork(true); |
||||
compile.getOptions().getForkOptions().setJavaHome(new File(javaHome)); |
||||
compile.getOptions().getForkOptions().setExecutable(javaHome + "/bin/javac"); |
||||
}); |
||||
List<String> args = compile.getOptions().getCompilerArgs(); |
||||
if (!args.contains("-parameters")) { |
||||
args.add("-parameters"); |
||||
} |
||||
}); |
||||
} |
||||
|
||||
private void withOptionalBuildJavaHome(Project project, Consumer<String> consumer) { |
||||
String buildJavaHome = (String) project.findProperty("buildJavaHome"); |
||||
if (buildJavaHome != null && !buildJavaHome.isEmpty()) { |
||||
consumer.accept(buildJavaHome); |
||||
} |
||||
} |
||||
|
||||
private void configureSpringJavaFormat(Project project) { |
||||
project.getPlugins().apply(SpringJavaFormatPlugin.class); |
||||
project.getTasks().withType(FormatTask.class, (formatTask) -> formatTask.setEncoding("UTF-8")); |
||||
project.getPlugins().apply(CheckstylePlugin.class); |
||||
CheckstyleExtension checkstyle = project.getExtensions().getByType(CheckstyleExtension.class); |
||||
checkstyle.setToolVersion("8.29"); |
||||
checkstyle.getConfigDirectory().set(project.getRootProject().file("src/checkstyle")); |
||||
String version = SpringJavaFormatPlugin.class.getPackage().getImplementationVersion(); |
||||
DependencySet checkstyleDependencies = project.getConfigurations().getByName("checkstyle").getDependencies(); |
||||
checkstyleDependencies |
||||
.add(project.getDependencies().create("io.spring.javaformat:spring-javaformat-checkstyle:" + version)); |
||||
checkstyleDependencies |
||||
.add(project.getDependencies().create("io.spring.nohttp:nohttp-checkstyle:0.0.3.RELEASE")); |
||||
} |
||||
|
||||
void copyLegalFiles(Project project, CopySpec metaInf) { |
||||
copyNoticeFile(project, metaInf); |
||||
copyLicenseFile(project, metaInf); |
||||
} |
||||
|
||||
void copyNoticeFile(Project project, CopySpec metaInf) { |
||||
try { |
||||
InputStream notice = getClass().getClassLoader().getResourceAsStream("NOTICE.txt"); |
||||
String noticeContent = FileCopyUtils.copyToString(new InputStreamReader(notice, StandardCharsets.UTF_8)) |
||||
.replace("${version}", project.getVersion().toString()); |
||||
TextResourceFactory resourceFactory = project.getResources().getText(); |
||||
File file = createLegalFile(resourceFactory.fromString(noticeContent).asFile(), "NOTICE.txt"); |
||||
metaInf.from(file); |
||||
} |
||||
catch (IOException ex) { |
||||
throw new GradleException("Failed to copy NOTICE.txt", ex); |
||||
} |
||||
} |
||||
|
||||
void copyLicenseFile(Project project, CopySpec metaInf) { |
||||
URL license = getClass().getClassLoader().getResource("LICENSE.txt"); |
||||
try { |
||||
TextResourceFactory resourceFactory = project.getResources().getText(); |
||||
File file = createLegalFile(resourceFactory.fromUri(license.toURI()).asFile(), "LICENSE.txt"); |
||||
metaInf.from(file); |
||||
} |
||||
catch (URISyntaxException ex) { |
||||
throw new GradleException("Failed to copy LICENSE.txt", ex); |
||||
} |
||||
} |
||||
|
||||
File createLegalFile(File source, String filename) { |
||||
File legalFile = new File(source.getParentFile(), filename); |
||||
source.renameTo(legalFile); |
||||
return legalFile; |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,116 @@
@@ -0,0 +1,116 @@
|
||||
/* |
||||
* Copyright 2012-2020 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 org.springframework.boot.build; |
||||
|
||||
import org.apache.maven.artifact.repository.MavenArtifactRepository; |
||||
import org.gradle.api.Project; |
||||
import org.gradle.api.plugins.JavaPlugin; |
||||
import org.gradle.api.plugins.JavaPluginExtension; |
||||
import org.gradle.api.publish.PublishingExtension; |
||||
import org.gradle.api.publish.maven.MavenPom; |
||||
import org.gradle.api.publish.maven.MavenPomDeveloperSpec; |
||||
import org.gradle.api.publish.maven.MavenPomIssueManagement; |
||||
import org.gradle.api.publish.maven.MavenPomLicenseSpec; |
||||
import org.gradle.api.publish.maven.MavenPomOrganization; |
||||
import org.gradle.api.publish.maven.MavenPomScm; |
||||
import org.gradle.api.publish.maven.MavenPublication; |
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin; |
||||
|
||||
/** |
||||
* Applies Maven Publishing conventions to projects that are part of Spring Boot's build. |
||||
* Conventions are applied in response to various plugins being applied. |
||||
* |
||||
* When the {@link MavenPublishPlugin Maven Publish plugin} is applied: |
||||
* |
||||
* <ul> |
||||
* <li>If the {@code deploymentRepository} property has been set, a |
||||
* {@link MavenArtifactRepository Maven artifact repository} is configured to publish to |
||||
* it. |
||||
* <li>The poms of all {@link MavenPublication Maven publications} are customized to meet |
||||
* Maven Central's requirements. |
||||
* </ul> |
||||
* |
||||
* <p/> |
||||
* |
||||
* @author Andy Wilkinson |
||||
* @author Christoph Dreis |
||||
* @author Mike Smithson |
||||
*/ |
||||
class MavenPublishingConventions { |
||||
|
||||
void applyPublishingConventions(Project project) { |
||||
project.getPlugins().withType(MavenPublishPlugin.class).all((mavenPublish) -> { |
||||
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class); |
||||
if (project.hasProperty("deploymentRepository")) { |
||||
publishing.getRepositories().maven((mavenRepository) -> { |
||||
mavenRepository.setUrl(project.property("deploymentRepository")); |
||||
mavenRepository.setName("deployment"); |
||||
}); |
||||
} |
||||
publishing.getPublications().withType(MavenPublication.class) |
||||
.all((mavenPublication) -> customizePom(mavenPublication.getPom(), project)); |
||||
project.getPlugins().withType(JavaPlugin.class).all((javaPlugin) -> { |
||||
JavaPluginExtension extension = project.getExtensions().getByType(JavaPluginExtension.class); |
||||
extension.withJavadocJar(); |
||||
extension.withSourcesJar(); |
||||
}); |
||||
}); |
||||
} |
||||
|
||||
private void customizePom(MavenPom pom, Project project) { |
||||
pom.getUrl().set("https://projects.spring.io/spring-boot/#"); |
||||
pom.getDescription().set(project.provider(project::getDescription)); |
||||
pom.organization(this::customizeOrganization); |
||||
pom.licenses(this::customizeLicences); |
||||
pom.developers(this::customizeDevelopers); |
||||
pom.scm(this::customizeScm); |
||||
pom.issueManagement(this::customizeIssueManagement); |
||||
} |
||||
|
||||
private void customizeOrganization(MavenPomOrganization organization) { |
||||
organization.getName().set("Pivotal Software, Inc."); |
||||
organization.getUrl().set("https://spring.io"); |
||||
} |
||||
|
||||
private void customizeLicences(MavenPomLicenseSpec licences) { |
||||
licences.license((licence) -> { |
||||
licence.getName().set("Apache License, Version 2.0"); |
||||
licence.getUrl().set("http://www.apache.org/licenses/LICENSE-2.0"); |
||||
}); |
||||
} |
||||
|
||||
private void customizeDevelopers(MavenPomDeveloperSpec developers) { |
||||
developers.developer((developer) -> { |
||||
developer.getName().set("Pivotal"); |
||||
developer.getEmail().set("info@pivotal.io"); |
||||
developer.getOrganization().set("Pivotal Software, Inc."); |
||||
developer.getOrganizationUrl().set("https://www.spring.io"); |
||||
}); |
||||
} |
||||
|
||||
private void customizeScm(MavenPomScm scm) { |
||||
scm.getConnection().set("scm:git:git://github.com/spring-projects/spring-boot.git"); |
||||
scm.getDeveloperConnection().set("scm:git:ssh://git@github.com/spring-projects/spring-boot.git"); |
||||
scm.getUrl().set("https://github.com/spring-projects/spring-boot"); |
||||
} |
||||
|
||||
private void customizeIssueManagement(MavenPomIssueManagement issueManagement) { |
||||
issueManagement.getSystem().set("GitHub"); |
||||
issueManagement.getUrl().set("https://github.com/spring-projects/spring-boot/issues"); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue