Merge branch '3.2.x' into 3.3.x

Closes gh-41273
This commit is contained in:
Andy Wilkinson 2024-06-28 15:47:54 +01:00
commit 55ac058385
31 changed files with 276 additions and 513 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2024 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.
@ -21,15 +21,13 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
@ -42,54 +40,30 @@ import org.springframework.util.PropertyPlaceholderHelper;
*
* @author Andy Wilkinson
*/
public class ExtractResources extends DefaultTask {
public abstract class ExtractResources extends DefaultTask {
private final PropertyPlaceholderHelper propertyPlaceholderHelper = new PropertyPlaceholderHelper("${", "}");
private final Map<String, String> properties = new HashMap<>();
private final DirectoryProperty destinationDirectory;
private List<String> resourceNames = new ArrayList<>();
public ExtractResources() {
this.destinationDirectory = getProject().getObjects().directoryProperty();
}
@Input
public List<String> getResourceNames() {
return this.resourceNames;
}
public void setResourcesNames(List<String> resourceNames) {
this.resourceNames = resourceNames;
}
public abstract ListProperty<String> getResourceNames();
@OutputDirectory
public DirectoryProperty getDestinationDirectory() {
return this.destinationDirectory;
}
public void property(String name, String value) {
this.properties.put(name, value);
}
public abstract DirectoryProperty getDestinationDirectory();
@Input
public Map<String, String> getProperties() {
return this.properties;
}
public abstract MapProperty<String, String> getProperties();
@TaskAction
void extractResources() throws IOException {
for (String resourceName : this.resourceNames) {
for (String resourceName : getResourceNames().get()) {
InputStream resourceStream = getClass().getClassLoader().getResourceAsStream(resourceName);
if (resourceStream == null) {
throw new GradleException("Resource '" + resourceName + "' does not exist");
}
String resource = FileCopyUtils.copyToString(new InputStreamReader(resourceStream, StandardCharsets.UTF_8));
resource = this.propertyPlaceholderHelper.replacePlaceholders(resource, this.properties::get);
resource = this.propertyPlaceholderHelper.replacePlaceholders(resource, getProperties().get()::get);
FileCopyUtils.copy(resource,
new FileWriter(this.destinationDirectory.file(resourceName).get().getAsFile()));
new FileWriter(getDestinationDirectory().file(resourceName).get().getAsFile()));
}
}

View File

@ -129,8 +129,8 @@ class JavaConventions {
ExtractResources extractLegalResources = project.getTasks()
.create("extractLegalResources", ExtractResources.class);
extractLegalResources.getDestinationDirectory().set(project.getLayout().getBuildDirectory().dir("legal"));
extractLegalResources.setResourcesNames(Arrays.asList("LICENSE.txt", "NOTICE.txt"));
extractLegalResources.property("version", project.getVersion().toString());
extractLegalResources.getResourceNames().set(Arrays.asList("LICENSE.txt", "NOTICE.txt"));
extractLegalResources.getProperties().put("version", project.getVersion().toString());
SourceSetContainer sourceSets = project.getExtensions().getByType(SourceSetContainer.class);
Set<String> sourceJarTaskNames = sourceSets.stream()
.map(SourceSet::getSourcesJarTaskName)

View File

@ -1,5 +1,5 @@
/*
* Copyright 2021-2023 the original author or authors.
* Copyright 2021-2024 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.
@ -18,7 +18,6 @@ package org.springframework.boot.build;
import org.gradle.api.DefaultTask;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputDirectory;
@ -31,45 +30,29 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class SyncAppSource extends DefaultTask {
private final DirectoryProperty sourceDirectory;
private final DirectoryProperty destinationDirectory;
private final Property<String> pluginVersion;
public abstract class SyncAppSource extends DefaultTask {
public SyncAppSource() {
ObjectFactory objects = getProject().getObjects();
this.sourceDirectory = objects.directoryProperty();
this.destinationDirectory = objects.directoryProperty();
this.pluginVersion = objects.property(String.class)
.convention(getProject().provider(() -> getProject().getVersion().toString()));
getPluginVersion().convention(getProject().provider(() -> getProject().getVersion().toString()));
}
@InputDirectory
public abstract DirectoryProperty getSourceDirectory();
@OutputDirectory
public abstract DirectoryProperty getDestinationDirectory();
@Input
public abstract Property<String> getPluginVersion();
@TaskAction
void syncAppSources() {
getProject().sync((copySpec) -> {
copySpec.from(this.sourceDirectory);
copySpec.into(this.destinationDirectory);
copySpec.from(getSourceDirectory());
copySpec.into(getDestinationDirectory());
copySpec.filter((line) -> line.replace("id \"org.springframework.boot\"",
"id \"org.springframework.boot\" version \"" + getProject().getVersion() + "\""));
});
}
@InputDirectory
public DirectoryProperty getSourceDirectory() {
return this.sourceDirectory;
}
@OutputDirectory
public DirectoryProperty getDestinationDirectory() {
return this.destinationDirectory;
}
@Input
public Property<String> getPluginVersion() {
return this.pluginVersion;
}
}

View File

@ -28,11 +28,15 @@ import java.util.LinkedHashSet;
import java.util.List;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.Callable;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskAction;
@ -48,47 +52,45 @@ import org.springframework.core.CollectionFactory;
* @author Andy Wilkinson
* @author Scott Frederick
*/
public class AutoConfigurationMetadata extends DefaultTask {
public abstract class AutoConfigurationMetadata extends DefaultTask {
private static final String COMMENT_START = "#";
private final String moduleName;
private SourceSet sourceSet;
private File outputFile;
private FileCollection classesDirectories;
public AutoConfigurationMetadata() {
getInputs()
.file((Callable<File>) () -> new File(this.sourceSet.getOutput().getResourcesDir(),
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"))
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("org.springframework.boot.autoconfigure.AutoConfiguration");
dependsOn((Callable<String>) () -> this.sourceSet.getProcessResourcesTaskName());
getProject().getConfigurations()
.maybeCreate(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME);
this.moduleName = getProject().getName();
}
public void setSourceSet(SourceSet sourceSet) {
this.sourceSet = sourceSet;
getAutoConfigurationImports().set(new File(sourceSet.getOutput().getResourcesDir(),
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports"));
this.classesDirectories = sourceSet.getOutput().getClassesDirs();
dependsOn(sourceSet.getOutput());
}
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
abstract RegularFileProperty getAutoConfigurationImports();
@OutputFile
public File getOutputFile() {
return this.outputFile;
}
public abstract RegularFileProperty getOutputFile();
public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
@Classpath
FileCollection getClassesDirectories() {
return this.classesDirectories;
}
@TaskAction
void documentAutoConfiguration() throws IOException {
Properties autoConfiguration = readAutoConfiguration();
getOutputFile().getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(getOutputFile())) {
File outputFile = getOutputFile().get().getAsFile();
outputFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(outputFile)) {
autoConfiguration.store(writer, null);
}
}
@ -120,8 +122,7 @@ public class AutoConfigurationMetadata extends DefaultTask {
* @return auto-configurations
*/
private List<String> readAutoConfigurationsFile() throws IOException {
File file = new File(this.sourceSet.getOutput().getResourcesDir(),
"META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports");
File file = getAutoConfigurationImports().getAsFile().get();
if (!file.exists()) {
return Collections.emptyList();
}
@ -140,7 +141,7 @@ public class AutoConfigurationMetadata extends DefaultTask {
private File findClassFile(String className) {
String classFileName = className.replace(".", "/") + ".class";
for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) {
for (File classesDir : this.classesDirectories) {
File classFile = new File(classesDir, classFileName);
if (classFile.isFile()) {
return classFile;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -22,7 +22,6 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.lang.ArchCondition;
@ -94,10 +93,9 @@ public class AutoConfigurationPlugin implements Plugin<Project> {
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
task.setSourceSet(main);
task.dependsOn(main.getClassesTaskName());
task.setOutputFile(new File(project.getBuildDir(), "auto-configuration-metadata.properties"));
task.getOutputFile().set(new File(project.getBuildDir(), "auto-configuration-metadata.properties"));
project.getArtifacts()
.add(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME,
project.provider((Callable<File>) task::getOutputFile),
.add(AutoConfigurationPlugin.AUTO_CONFIGURATION_METADATA_CONFIGURATION_NAME, task.getOutputFile(),
(artifact) -> artifact.builtBy(task));
});
project.getPlugins().withType(ArchitecturePlugin.class, (architecturePlugin) -> {

View File

@ -31,6 +31,7 @@ import java.util.stream.Collectors;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
@ -42,12 +43,10 @@ import org.springframework.util.StringUtils;
*
* @author Andy Wilkinson
*/
public class DocumentAutoConfigurationClasses extends DefaultTask {
public abstract class DocumentAutoConfigurationClasses extends DefaultTask {
private FileCollection autoConfiguration;
private File outputDir;
@InputFiles
public FileCollection getAutoConfiguration() {
return this.autoConfiguration;
@ -58,13 +57,7 @@ public class DocumentAutoConfigurationClasses extends DefaultTask {
}
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract RegularFileProperty getOutputDir();
@TaskAction
void documentAutoConfigurationClasses() throws IOException {
@ -80,9 +73,10 @@ public class DocumentAutoConfigurationClasses extends DefaultTask {
}
private void writeTable(AutoConfiguration autoConfigurationClasses) throws IOException {
this.outputDir.mkdirs();
File outputDir = getOutputDir().getAsFile().get();
outputDir.mkdirs();
try (PrintWriter writer = new PrintWriter(
new FileWriter(new File(this.outputDir, autoConfigurationClasses.module + ".adoc")))) {
new FileWriter(new File(outputDir, autoConfigurationClasses.module + ".adoc")))) {
writer.println("[cols=\"4,1\"]");
writer.println("|===");
writer.println("| Configuration Class | Links");

View File

@ -154,7 +154,7 @@ public class BomExtension {
}
MavenExec generateEffectiveBom = this.project.getTasks()
.create("generateEffectiveBom", MavenExec.class);
generateEffectiveBom.setProjectDir(generatedBomDir);
generateEffectiveBom.getProjectDir().set(generatedBomDir);
File effectiveBom = new File(this.project.getBuildDir(),
"generated/effective-bom/" + this.project.getName() + "-effective-bom.xml");
generateEffectiveBom.args("--settings", "settings.xml", "help:effective-pom",

View File

@ -45,7 +45,7 @@ import org.springframework.boot.build.bom.bomr.version.DependencyVersion;
*
* @author Andy Wilkinson
*/
public class CheckBom extends DefaultTask {
public abstract class CheckBom extends DefaultTask {
private final BomExtension bom;

View File

@ -42,7 +42,7 @@ import org.springframework.web.client.RestTemplate;
* @author Andy Wilkinson
* @author Phillip Webb
*/
public class CheckLinks extends DefaultTask {
public abstract class CheckLinks extends DefaultTask {
private final BomExtension bom;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -48,7 +48,7 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckClasspathForConflicts extends DefaultTask {
public abstract class CheckClasspathForConflicts extends DefaultTask {
private final List<Predicate<String>> ignores = new ArrayList<>();

View File

@ -34,7 +34,7 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckClasspathForProhibitedDependencies extends DefaultTask {
public abstract class CheckClasspathForProhibitedDependencies extends DefaultTask {
private static final Set<String> PROHIBITED_GROUPS = Set.of("org.codehaus.groovy", "org.eclipse.jetty.toolchain",
"commons-logging", "org.apache.geronimo.specs", "com.sun.activation");

View File

@ -34,7 +34,7 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckClasspathForUnconstrainedDirectDependencies extends DefaultTask {
public abstract class CheckClasspathForUnconstrainedDirectDependencies extends DefaultTask {
private Configuration classpath;

View File

@ -48,7 +48,7 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckClasspathForUnnecessaryExclusions extends DefaultTask {
public abstract class CheckClasspathForUnnecessaryExclusions extends DefaultTask {
private static final Map<String, String> SPRING_BOOT_DEPENDENCIES_PROJECT = Collections.singletonMap("path",
":spring-boot-project:spring-boot-dependencies");

View File

@ -18,16 +18,15 @@ package org.springframework.boot.build.cli;
import java.io.File;
import java.security.MessageDigest;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.digest.DigestUtils;
import org.gradle.api.DefaultTask;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.RegularFile;
import org.gradle.api.provider.Provider;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.PathSensitive;
@ -42,62 +41,14 @@ import org.springframework.boot.build.artifacts.ArtifactRelease;
*
* @author Andy Wilkinson
*/
public class HomebrewFormula extends DefaultTask {
private Provider<RegularFile> archive;
private File template;
private File outputDir;
public abstract class HomebrewFormula extends DefaultTask {
public HomebrewFormula() {
getInputs().property("version", getProject().provider(getProject()::getVersion));
}
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public RegularFile getArchive() {
return this.archive.get();
}
public void setArchive(Provider<RegularFile> archive) {
this.archive = archive;
}
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public File getTemplate() {
return this.template;
}
public void setTemplate(File template) {
this.template = template;
}
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
protected void createDescriptor(Map<String, Object> additionalProperties) {
getProject().copy((copy) -> {
copy.from(this.template);
copy.into(this.outputDir);
copy.expand(getProperties(additionalProperties));
});
}
private Map<String, Object> getProperties(Map<String, Object> additionalProperties) {
Map<String, Object> properties = new HashMap<>(additionalProperties);
Project project = getProject();
properties.put("hash", sha256(this.archive.get().getAsFile()));
properties.put("repo", ArtifactRelease.forProject(project).getDownloadRepo());
properties.put("project", project);
return properties;
MapProperty<String, Object> properties = getProperties();
properties.put("hash", getArchive().map((archive) -> sha256(archive.getAsFile())));
getProperties().put("repo", ArtifactRelease.forProject(project).getDownloadRepo());
getProperties().put("version", project.getVersion().toString());
}
private String sha256(File file) {
@ -110,9 +61,27 @@ public class HomebrewFormula extends DefaultTask {
}
}
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public abstract RegularFileProperty getArchive();
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public abstract RegularFileProperty getTemplate();
@OutputDirectory
public abstract DirectoryProperty getOutputDir();
@Input
abstract MapProperty<String, Object> getProperties();
@TaskAction
void createFormula() {
createDescriptor(Collections.emptyMap());
getProject().copy((copy) -> {
copy.from(getTemplate());
copy.into(getOutputDir());
copy.expand(getProperties().get());
});
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2024 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.
@ -21,10 +21,8 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import org.gradle.api.DefaultTask;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
@ -37,38 +35,22 @@ import org.springframework.boot.build.constraints.ExtractVersionConstraints.Cons
*
* @author Andy Wilkinson
*/
public class DocumentConstrainedVersions extends DefaultTask {
private final SetProperty<ConstrainedVersion> constrainedVersions;
private File outputFile;
@Inject
public DocumentConstrainedVersions(ObjectFactory objectFactory) {
this.constrainedVersions = objectFactory.setProperty(ConstrainedVersion.class);
}
public abstract class DocumentConstrainedVersions extends DefaultTask {
@Input
public SetProperty<ConstrainedVersion> getConstrainedVersions() {
return this.constrainedVersions;
}
public abstract SetProperty<ConstrainedVersion> getConstrainedVersions();
@OutputFile
public File getOutputFile() {
return this.outputFile;
}
public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
}
public abstract RegularFileProperty getOutputFile();
@TaskAction
public void documentConstrainedVersions() throws IOException {
this.outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile))) {
File outputFile = getOutputFile().get().getAsFile();
outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("|===");
writer.println("| Group ID | Artifact ID | Version");
for (ConstrainedVersion constrainedVersion : this.constrainedVersions.get()) {
for (ConstrainedVersion constrainedVersion : getConstrainedVersions().get()) {
writer.println();
writer.printf("| `%s`%n", constrainedVersion.getGroup());
writer.printf("| `%s`%n", constrainedVersion.getArtifact());

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2024 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.
@ -21,10 +21,8 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import javax.inject.Inject;
import org.gradle.api.DefaultTask;
import org.gradle.api.model.ObjectFactory;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputFile;
@ -37,38 +35,22 @@ import org.springframework.boot.build.constraints.ExtractVersionConstraints.Vers
*
* @author Christoph Dreis
*/
public class DocumentVersionProperties extends DefaultTask {
private final SetProperty<VersionProperty> versionProperties;
private File outputFile;
@Inject
public DocumentVersionProperties(ObjectFactory objectFactory) {
this.versionProperties = objectFactory.setProperty(VersionProperty.class);
}
public abstract class DocumentVersionProperties extends DefaultTask {
@Input
public SetProperty<VersionProperty> getVersionProperties() {
return this.versionProperties;
}
public abstract SetProperty<VersionProperty> getVersionProperties();
@OutputFile
public File getOutputFile() {
return this.outputFile;
}
public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
}
public abstract RegularFileProperty getOutputFile();
@TaskAction
public void documentVersionProperties() throws IOException {
this.outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile))) {
File outputFile = getOutputFile().getAsFile().get();
outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("|===");
writer.println("| Library | Version Property");
for (VersionProperty versionProperty : this.versionProperties.get()) {
for (VersionProperty versionProperty : getVersionProperties().get()) {
writer.println();
writer.printf("| `%s`%n", versionProperty.getLibraryName());
writer.printf("| `%s`%n", versionProperty.getVersionProperty());

View File

@ -48,7 +48,7 @@ import org.springframework.boot.build.bom.Library;
*
* @author Andy Wilkinson
*/
public class ExtractVersionConstraints extends DefaultTask {
public abstract class ExtractVersionConstraints extends DefaultTask {
private final Configuration configuration;

View File

@ -46,21 +46,16 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckAdditionalSpringConfigurationMetadata extends SourceTask {
public abstract class CheckAdditionalSpringConfigurationMetadata extends SourceTask {
private final File projectDir;
private final RegularFileProperty reportLocation;
public CheckAdditionalSpringConfigurationMetadata() {
this.projectDir = getProject().getProjectDir();
this.reportLocation = getProject().getObjects().fileProperty();
}
@OutputFile
public RegularFileProperty getReportLocation() {
return this.reportLocation;
}
public abstract RegularFileProperty getReportLocation();
@Override
@InputFiles

View File

@ -32,6 +32,7 @@ import com.fasterxml.jackson.databind.ObjectMapper;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputFile;
@ -45,41 +46,23 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class CheckSpringConfigurationMetadata extends DefaultTask {
public abstract class CheckSpringConfigurationMetadata extends DefaultTask {
private List<String> exclusions = new ArrayList<>();
private final File projectDir;
private final RegularFileProperty reportLocation;
private final RegularFileProperty metadataLocation;
private final Path projectRoot;
public CheckSpringConfigurationMetadata() {
this.projectDir = getProject().getProjectDir();
this.metadataLocation = getProject().getObjects().fileProperty();
this.reportLocation = getProject().getObjects().fileProperty();
this.projectRoot = getProject().getProjectDir().toPath();
}
@OutputFile
public RegularFileProperty getReportLocation() {
return this.reportLocation;
}
public abstract RegularFileProperty getReportLocation();
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
public RegularFileProperty getMetadataLocation() {
return this.metadataLocation;
}
public void setExclusions(List<String> exclusions) {
this.exclusions = exclusions;
}
public abstract RegularFileProperty getMetadataLocation();
@Input
public List<String> getExclusions() {
return this.exclusions;
}
public abstract ListProperty<String> getExclusions();
@TaskAction
void check() throws JsonParseException, IOException {
@ -95,8 +78,8 @@ public class CheckSpringConfigurationMetadata extends DefaultTask {
@SuppressWarnings("unchecked")
private Report createReport() throws IOException, JsonParseException, JsonMappingException {
ObjectMapper objectMapper = new ObjectMapper();
File file = this.metadataLocation.get().getAsFile();
Report report = new Report(this.projectDir.toPath().relativize(file.toPath()));
File file = getMetadataLocation().get().getAsFile();
Report report = new Report(this.projectRoot.relativize(file.toPath()));
Map<String, Object> json = objectMapper.readValue(file, Map.class);
List<Map<String, Object>> properties = (List<Map<String, Object>>) json.get("properties");
for (Map<String, Object> property : properties) {
@ -109,7 +92,7 @@ public class CheckSpringConfigurationMetadata extends DefaultTask {
}
private boolean isExcluded(String propertyName) {
for (String exclusion : this.exclusions) {
for (String exclusion : getExclusions().get()) {
if (propertyName.equals(exclusion)) {
return true;
}

View File

@ -16,11 +16,11 @@
package org.springframework.boot.build.context.properties;
import java.io.File;
import java.io.IOException;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
@ -36,12 +36,10 @@ import org.springframework.boot.build.context.properties.Snippet.Config;
* @author Andy Wilkinson
* @author Phillip Webb
*/
public class DocumentConfigurationProperties extends DefaultTask {
public abstract class DocumentConfigurationProperties extends DefaultTask {
private FileCollection configurationPropertyMetadata;
private File outputDir;
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
public FileCollection getConfigurationPropertyMetadata() {
@ -53,13 +51,7 @@ public class DocumentConfigurationProperties extends DefaultTask {
}
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract DirectoryProperty getOutputDir();
@TaskAction
void documentConfigurationProperties() throws IOException {
@ -83,7 +75,7 @@ public class DocumentConfigurationProperties extends DefaultTask {
snippets.add("application-properties.testcontainers", "Testcontainers Properties",
this::testcontainersPrefixes);
snippets.add("application-properties.testing", "Testing Properties", this::testingPrefixes);
snippets.writeTo(this.outputDir.toPath());
snippets.writeTo(getOutputDir().getAsFile().get().toPath());
}
private void corePrefixes(Config config) {

View File

@ -39,16 +39,13 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class DocumentDevtoolsPropertyDefaults extends DefaultTask {
public abstract class DocumentDevtoolsPropertyDefaults extends DefaultTask {
private final Configuration devtools;
private final RegularFileProperty outputFile;
public DocumentDevtoolsPropertyDefaults() {
this.devtools = getProject().getConfigurations().create("devtools");
this.outputFile = getProject().getObjects().fileProperty();
this.outputFile.convention(getProject().getLayout()
getOutputFile().convention(getProject().getLayout()
.getBuildDirectory()
.file("generated/docs/using/devtools-property-defaults.adoc"));
Map<String, String> dependency = new HashMap<>();
@ -63,9 +60,7 @@ public class DocumentDevtoolsPropertyDefaults extends DefaultTask {
}
@OutputFile
public RegularFileProperty getOutputFile() {
return this.outputFile;
}
public abstract RegularFileProperty getOutputFile();
@TaskAction
void documentPropertyDefaults() throws IOException {
@ -86,7 +81,7 @@ public class DocumentDevtoolsPropertyDefaults extends DefaultTask {
}
private void documentProperties(Map<String, String> properties) throws IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile.getAsFile().get()))) {
try (PrintWriter writer = new PrintWriter(new FileWriter(getOutputFile().getAsFile().get()))) {
writer.println("[cols=\"3,1\"]");
writer.println("|===");
writer.println("| Name | Default Value");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -34,6 +34,7 @@ import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.ListProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.Input;
@ -47,29 +48,17 @@ import org.gradle.internal.jvm.Jvm;
*
* @author Andy Wilkinson
*/
public class ApplicationRunner extends DefaultTask {
private final RegularFileProperty output = getProject().getObjects().fileProperty();
private final ListProperty<String> args = getProject().getObjects().listProperty(String.class);
private final Property<String> mainClass = getProject().getObjects().property(String.class);
private final Property<String> expectedLogging = getProject().getObjects().property(String.class);
private final Property<String> applicationJar = getProject().getObjects()
.property(String.class)
.convention("/opt/apps/myapp.jar");
private final Map<String, String> normalizations = new HashMap<>();
public abstract class ApplicationRunner extends DefaultTask {
private FileCollection classpath;
@OutputFile
public RegularFileProperty getOutput() {
return this.output;
public ApplicationRunner() {
getApplicationJar().convention("/opt/apps/myapp.jar");
}
@OutputFile
public abstract RegularFileProperty getOutput();
@Classpath
public FileCollection getClasspath() {
return this.classpath;
@ -80,37 +69,27 @@ public class ApplicationRunner extends DefaultTask {
}
@Input
public ListProperty<String> getArgs() {
return this.args;
}
public abstract ListProperty<String> getArgs();
@Input
public Property<String> getMainClass() {
return this.mainClass;
}
public abstract Property<String> getMainClass();
@Input
public Property<String> getExpectedLogging() {
return this.expectedLogging;
}
public abstract Property<String> getExpectedLogging();
@Input
Map<String, String> getNormalizations() {
return this.normalizations;
}
abstract MapProperty<String, String> getNormalizations();
@Input
public Property<String> getApplicationJar() {
return this.applicationJar;
}
abstract Property<String> getApplicationJar();
public void normalizeTomcatPort() {
this.normalizations.put("(Tomcat started on port )[\\d]+( \\(http\\))", "$18080$2");
this.normalizations.put("(Tomcat initialized with port )[\\d]+( \\(http\\))", "$18080$2");
getNormalizations().put("(Tomcat started on port )[\\d]+( \\(http\\))", "$18080$2");
getNormalizations().put("(Tomcat initialized with port )[\\d]+( \\(http\\))", "$18080$2");
}
public void normalizeLiveReloadPort() {
this.normalizations.put("(LiveReload server is running on port )[\\d]+", "$135729");
getNormalizations().put("(LiveReload server is running on port )[\\d]+", "$135729");
}
@TaskAction
@ -123,9 +102,9 @@ public class ApplicationRunner extends DefaultTask {
.stream()
.map(File::getAbsolutePath)
.collect(Collectors.joining(File.pathSeparator)));
command.add(this.mainClass.get());
command.addAll(this.args.get());
File outputFile = this.output.getAsFile().get();
command.add(getMainClass().get());
command.addAll(getArgs().get());
File outputFile = getOutput().getAsFile().get();
Process process = new ProcessBuilder().redirectOutput(outputFile)
.redirectError(outputFile)
.command(command)
@ -137,7 +116,7 @@ public class ApplicationRunner extends DefaultTask {
private void awaitLogging(Process process) {
long end = System.currentTimeMillis() + 60000;
String expectedLogging = this.expectedLogging.get();
String expectedLogging = getExpectedLogging().get();
while (System.currentTimeMillis() < end) {
for (String line : outputLines()) {
if (line.contains(expectedLogging)) {
@ -152,7 +131,7 @@ public class ApplicationRunner extends DefaultTask {
}
private List<String> outputLines() {
Path outputPath = this.output.get().getAsFile().toPath();
Path outputPath = getOutput().get().getAsFile().toPath();
try {
return Files.readAllLines(outputPath);
}
@ -164,7 +143,7 @@ public class ApplicationRunner extends DefaultTask {
private void normalizeLogging() {
List<String> outputLines = outputLines();
List<String> normalizedLines = normalize(outputLines);
Path outputPath = this.output.get().getAsFile().toPath();
Path outputPath = getOutput().get().getAsFile().toPath();
try {
Files.write(outputPath, normalizedLines);
}
@ -175,9 +154,9 @@ public class ApplicationRunner extends DefaultTask {
private List<String> normalize(List<String> lines) {
List<String> normalizedLines = lines;
Map<String, String> normalizations = new HashMap<>(this.normalizations);
Map<String, String> normalizations = new HashMap<>(getNormalizations().get());
normalizations.put("(Starting .* using Java .* with PID [\\d]+ \\().*( started by ).*( in ).*(\\))",
"$1" + this.applicationJar.get() + "$2myuser$3/opt/apps/$4");
"$1" + getApplicationJar().get() + "$2myuser$3/opt/apps/$4");
for (Entry<String, String> normalization : normalizations.entrySet()) {
Pattern pattern = Pattern.compile(normalization.getKey());
normalizedLines = normalize(normalizedLines, pattern, normalization.getValue());

View File

@ -21,10 +21,12 @@ import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.Map;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.provider.MapProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.OutputDirectory;
@ -39,46 +41,22 @@ import org.springframework.boot.build.mavenplugin.PluginXmlParser.Plugin;
*
* @author Andy Wilkinson
*/
public class DocumentPluginGoals extends DefaultTask {
public abstract class DocumentPluginGoals extends DefaultTask {
private final PluginXmlParser parser = new PluginXmlParser();
private File pluginXml;
private File outputDir;
private Map<String, String> goalSections;
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract DirectoryProperty getOutputDir();
@Input
public Map<String, String> getGoalSections() {
return this.goalSections;
}
public void setGoalSections(Map<String, String> goalSections) {
this.goalSections = goalSections;
}
public abstract MapProperty<String, String> getGoalSections();
@InputFile
public File getPluginXml() {
return this.pluginXml;
}
public void setPluginXml(File pluginXml) {
this.pluginXml = pluginXml;
}
public abstract RegularFileProperty getPluginXml();
@TaskAction
public void documentPluginGoals() throws IOException {
Plugin plugin = this.parser.parse(this.pluginXml);
Plugin plugin = this.parser.parse(getPluginXml().getAsFile().get());
writeOverview(plugin);
for (Mojo mojo : plugin.getMojos()) {
documentMojo(plugin, mojo);
@ -86,7 +64,8 @@ public class DocumentPluginGoals extends DefaultTask {
}
private void writeOverview(Plugin plugin) throws IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(new File(this.outputDir, "overview.adoc")))) {
try (PrintWriter writer = new PrintWriter(
new FileWriter(new File(getOutputDir().getAsFile().get(), "overview.adoc")))) {
writer.println("[cols=\"1,3\"]");
writer.println("|===");
writer.println("| Goal | Description");
@ -101,7 +80,8 @@ public class DocumentPluginGoals extends DefaultTask {
}
private void documentMojo(Plugin plugin, Mojo mojo) throws IOException {
try (PrintWriter writer = new PrintWriter(new FileWriter(new File(this.outputDir, mojo.getGoal() + ".adoc")))) {
try (PrintWriter writer = new PrintWriter(
new FileWriter(new File(getOutputDir().getAsFile().get(), mojo.getGoal() + ".adoc")))) {
String sectionId = goalSectionId(mojo, true);
writer.printf("[[%s]]%n", sectionId);
writer.printf("= `%s:%s`%n%n", plugin.getGoalPrefix(), mojo.getGoal());
@ -143,7 +123,7 @@ public class DocumentPluginGoals extends DefaultTask {
}
private String goalSectionId(Mojo mojo, boolean innerReference) {
String goalSection = this.goalSections.get(mojo.getGoal());
String goalSection = getGoalSections().getting(mojo.getGoal()).get();
if (goalSection == null) {
throw new IllegalStateException("Goal '" + mojo.getGoal() + "' has not be assigned to a section");
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -24,8 +24,12 @@ import java.nio.file.Path;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.JavaExec;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.TaskExecutionException;
import org.gradle.process.internal.ExecException;
@ -37,29 +41,29 @@ import org.slf4j.LoggerFactory;
*
* @author Andy Wilkinson
*/
public class MavenExec extends JavaExec {
public abstract class MavenExec extends JavaExec {
private final Logger log = LoggerFactory.getLogger(MavenExec.class);
private File projectDir;
public MavenExec() {
setClasspath(mavenConfiguration(getProject()));
args("--batch-mode");
getMainClass().set("org.apache.maven.cli.MavenCli");
getPom().set(getProjectDir().file("pom.xml"));
}
public void setProjectDir(File projectDir) {
this.projectDir = projectDir;
getInputs().file(new File(projectDir, "pom.xml"))
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("pom");
}
@Internal
public abstract DirectoryProperty getProjectDir();
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
abstract RegularFileProperty getPom();
@Override
public void exec() {
workingDir(this.projectDir);
systemProperty("maven.multiModuleProjectDirectory", this.projectDir.getAbsolutePath());
File workingDir = getProjectDir().getAsFile().get();
workingDir(workingDir);
systemProperty("maven.multiModuleProjectDirectory", workingDir.getAbsolutePath());
try {
Path logFile = Files.createTempFile(getName(), ".log");
try {
@ -97,9 +101,4 @@ public class MavenExec extends JavaExec {
});
}
@Internal
public File getProjectDir() {
return this.projectDir;
}
}

View File

@ -168,7 +168,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
project.getObjects().named(DocsType.class, "maven-repository")));
RuntimeClasspathMavenRepository runtimeClasspathMavenRepository = project.getTasks()
.create("runtimeClasspathMavenRepository", RuntimeClasspathMavenRepository.class);
runtimeClasspathMavenRepository.getOutputDirectory()
runtimeClasspathMavenRepository.getOutputDir()
.set(new File(project.getBuildDir(), "runtime-classpath-repository"));
project.getDependencies()
.components((components) -> components.all(MavenRepositoryComponentMetadataRule.class));
@ -195,8 +195,8 @@ public class MavenPluginPlugin implements Plugin<Project> {
private void addDocumentPluginGoalsTask(Project project, MavenExec generatePluginDescriptorTask) {
DocumentPluginGoals task = project.getTasks().create("documentPluginGoals", DocumentPluginGoals.class);
File pluginXml = new File(generatePluginDescriptorTask.getOutputs().getFiles().getSingleFile(), "plugin.xml");
task.setPluginXml(pluginXml);
task.setOutputDir(new File(project.getBuildDir(), "generated/docs/maven-plugin-goals/"));
task.getPluginXml().set(pluginXml);
task.getOutputDir().set(new File(project.getBuildDir(), "generated/docs/maven-plugin-goals/"));
task.dependsOn(generatePluginDescriptorTask);
}
@ -210,7 +210,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
private MavenExec createGenerateHelpMojoTask(Project project, File helpMojoDir) {
MavenExec task = project.getTasks().create("generateHelpMojo", MavenExec.class);
task.setProjectDir(helpMojoDir);
task.getProjectDir().set(helpMojoDir);
task.args("org.apache.maven.plugins:maven-plugin-plugin:3.6.1:helpmojo");
task.getOutputs().dir(new File(helpMojoDir, "target/generated-sources/plugin"));
return task;
@ -261,7 +261,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
FormatHelpMojoSource formatHelpMojoSource = project.getTasks()
.create("formatHelpMojoSource", FormatHelpMojoSource.class);
formatHelpMojoSource.setGenerator(generateHelpMojoTask);
formatHelpMojoSource.setOutputDir(generatedHelpMojoDir);
formatHelpMojoSource.getOutputDir().set(generatedHelpMojoDir);
return formatHelpMojoSource;
}
@ -284,7 +284,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
.dir(new File(mavenDir, "target/classes/org"))
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("plugin classes");
generatePluginDescriptor.setProjectDir(mavenDir);
generatePluginDescriptor.getProjectDir().set(mavenDir);
return generatePluginDescriptor;
}
@ -295,8 +295,9 @@ public class MavenPluginPlugin implements Plugin<Project> {
private void addPrepareMavenBinariesTask(Project project) {
TaskProvider<PrepareMavenBinaries> task = project.getTasks()
.register("prepareMavenBinaries", PrepareMavenBinaries.class, (prepareMavenBinaries) -> prepareMavenBinaries
.setOutputDir(new File(project.getBuildDir(), "maven-binaries")));
.register("prepareMavenBinaries", PrepareMavenBinaries.class,
(prepareMavenBinaries) -> prepareMavenBinaries.getOutputDir()
.set(new File(project.getBuildDir(), "maven-binaries")));
project.getTasks()
.getByName(IntegrationTestPlugin.INT_TEST_TASK_NAME)
.getInputs()
@ -324,12 +325,10 @@ public class MavenPluginPlugin implements Plugin<Project> {
.map((dir) -> dir.file("extracted-versions.properties")));
}
public static class FormatHelpMojoSource extends DefaultTask {
public abstract static class FormatHelpMojoSource extends DefaultTask {
private Task generator;
private File outputDir;
void setGenerator(Task generator) {
this.generator = generator;
getInputs().files(this.generator)
@ -338,13 +337,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
}
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract DirectoryProperty getOutputDir();
@TaskAction
void syncAndFormat() {
@ -357,7 +350,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
private void save(File output, FileEdit edit) {
Path relativePath = output.toPath().relativize(edit.getFile().toPath());
Path outputLocation = this.outputDir.toPath().resolve(relativePath);
Path outputLocation = getOutputDir().getAsFile().get().toPath().resolve(relativePath);
try {
Files.createDirectories(outputLocation.getParent());
Files.writeString(outputLocation, edit.getFormattedContent());
@ -401,21 +394,16 @@ public class MavenPluginPlugin implements Plugin<Project> {
}
public static class RuntimeClasspathMavenRepository extends DefaultTask {
public abstract static class RuntimeClasspathMavenRepository extends DefaultTask {
private final Configuration runtimeClasspath;
private final DirectoryProperty outputDirectory;
public RuntimeClasspathMavenRepository() {
this.runtimeClasspath = getProject().getConfigurations().getByName("runtimeClasspathWithMetadata");
this.outputDirectory = getProject().getObjects().directoryProperty();
}
@OutputDirectory
public DirectoryProperty getOutputDirectory() {
return this.outputDirectory;
}
public abstract DirectoryProperty getOutputDir();
@Classpath
public Configuration getRuntimeClasspath() {
@ -429,7 +417,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
String fileName = result.getFile()
.getName()
.replace(identifier.getVersion() + "-" + identifier.getVersion(), identifier.getVersion());
File repositoryLocation = this.outputDirectory
File repositoryLocation = getOutputDir()
.dir(identifier.getGroup().replace('.', '/') + "/" + identifier.getModule() + "/"
+ identifier.getVersion() + "/" + fileName)
.get()
@ -448,16 +436,10 @@ public class MavenPluginPlugin implements Plugin<Project> {
}
public static class ExtractVersionProperties extends DefaultTask {
private final RegularFileProperty destination;
public abstract static class ExtractVersionProperties extends DefaultTask {
private FileCollection effectiveBoms;
public ExtractVersionProperties() {
this.destination = getProject().getObjects().fileProperty();
}
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
public FileCollection getEffectiveBoms() {
@ -469,9 +451,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
}
@OutputFile
public RegularFileProperty getDestination() {
return this.destination;
}
public abstract RegularFileProperty getDestination();
@TaskAction
public void extractVersionProperties() {
@ -481,7 +461,7 @@ public class MavenPluginPlugin implements Plugin<Project> {
}
private void writeProperties(Properties versions) {
File outputFile = this.destination.getAsFile().get();
File outputFile = getDestination().getAsFile().get();
outputFile.getParentFile().mkdirs();
try (Writer writer = new FileWriter(outputFile)) {
versions.store(writer, null);

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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,14 +16,11 @@
package org.springframework.boot.build.mavenplugin;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.Set;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.provider.SetProperty;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.OutputDirectory;
import org.gradle.api.tasks.TaskAction;
@ -33,38 +30,22 @@ import org.gradle.api.tasks.TaskAction;
*
* @author Andy Wilkinson
*/
public class PrepareMavenBinaries extends DefaultTask {
private final Set<String> versions = new LinkedHashSet<>();
private File outputDir;
public abstract class PrepareMavenBinaries extends DefaultTask {
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract DirectoryProperty getOutputDir();
@Input
public Set<String> getVersions() {
return this.versions;
}
public void versions(String... versions) {
this.versions.addAll(Arrays.asList(versions));
}
public abstract SetProperty<String> getVersions();
@TaskAction
public void prepareBinaries() {
for (String version : this.versions) {
for (String version : getVersions().get()) {
Configuration configuration = getProject().getConfigurations()
.detachedConfiguration(
getProject().getDependencies().create("org.apache.maven:apache-maven:" + version + ":bin@zip"));
getProject()
.copy((copy) -> copy.into(this.outputDir).from(getProject().zipTree(configuration.getSingleFile())));
.copy((copy) -> copy.into(getOutputDir()).from(getProject().zipTree(configuration.getSingleFile())));
}
}

View File

@ -33,6 +33,7 @@ import java.util.stream.Stream;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.file.FileCollection;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputDirectory;
@ -47,12 +48,10 @@ import org.springframework.util.StringUtils;
*
* @author Andy Wilkinson
*/
public class DocumentStarters extends DefaultTask {
public abstract class DocumentStarters extends DefaultTask {
private final Configuration starters;
private File outputDir;
public DocumentStarters() {
this.starters = getProject().getConfigurations().create("starters");
getProject().getGradle().projectsEvaluated((gradle) -> {
@ -68,13 +67,7 @@ public class DocumentStarters extends DefaultTask {
}
@OutputDirectory
public File getOutputDir() {
return this.outputDir;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
public abstract DirectoryProperty getOutputDir();
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
@ -106,7 +99,7 @@ public class DocumentStarters extends DefaultTask {
}
private void writeTable(String name, Stream<Starter> starters) {
File output = new File(this.outputDir, name + ".adoc");
File output = new File(getOutputDir().getAsFile().get(), name + ".adoc");
output.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(output))) {
writer.println("|===");

View File

@ -32,6 +32,7 @@ import java.util.TreeSet;
import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.PathSensitive;
@ -46,12 +47,10 @@ import org.springframework.util.StringUtils;
*
* @author Andy Wilkinson
*/
public class DocumentTestSlices extends DefaultTask {
public abstract class DocumentTestSlices extends DefaultTask {
private FileCollection testSlices;
private File outputFile;
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
public FileCollection getTestSlices() {
@ -63,13 +62,7 @@ public class DocumentTestSlices extends DefaultTask {
}
@OutputFile
public File getOutputFile() {
return this.outputFile;
}
public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
}
public abstract RegularFileProperty getOutputFile();
@TaskAction
void documentTestSlices() throws IOException {
@ -94,8 +87,9 @@ public class DocumentTestSlices extends DefaultTask {
}
private void writeTable(Set<TestSlice> testSlices) throws IOException {
this.outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(this.outputFile))) {
File outputFile = getOutputFile().getAsFile().get();
outputFile.getParentFile().mkdirs();
try (PrintWriter writer = new PrintWriter(new FileWriter(outputFile))) {
writer.println("[cols=\"d,a\"]");
writer.println("|===");
writer.println("| Test slice | Imported auto-configuration");

View File

@ -1,5 +1,5 @@
/*
* Copyright 2012-2023 the original author or authors.
* Copyright 2012-2024 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.
@ -32,7 +32,6 @@ import java.util.List;
import java.util.Properties;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.concurrent.Callable;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
@ -41,7 +40,12 @@ import org.gradle.api.DefaultTask;
import org.gradle.api.Task;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.file.FileCollection;
import org.gradle.api.file.RegularFileProperty;
import org.gradle.api.tasks.Classpath;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.OutputFile;
import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.TaskAction;
@ -59,44 +63,57 @@ import org.springframework.util.StringUtils;
*
* @author Andy Wilkinson
*/
public class TestSliceMetadata extends DefaultTask {
public abstract class TestSliceMetadata extends DefaultTask {
private SourceSet sourceSet;
private FileCollection classpath;
private File outputFile;
private FileCollection importsFiles;
private FileCollection classesDirs;
public TestSliceMetadata() {
getInputs().dir((Callable<File>) () -> this.sourceSet.getOutput().getResourcesDir())
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("resources");
dependsOn((Callable<String>) () -> this.sourceSet.getProcessResourcesTaskName());
getInputs().files((Callable<FileCollection>) () -> this.sourceSet.getOutput().getClassesDirs())
.withPathSensitivity(PathSensitivity.RELATIVE)
.withPropertyName("classes");
Configuration testSliceMetadata = getProject().getConfigurations().maybeCreate("testSliceMetadata");
getProject().afterEvaluate((evaluated) -> evaluated.getArtifacts()
.add(testSliceMetadata.getName(), getOutputFile(), (artifact) -> artifact.builtBy(this)));
}
public void setSourceSet(SourceSet sourceSet) {
this.sourceSet = sourceSet;
this.classpath = sourceSet.getRuntimeClasspath();
this.importsFiles = getProject().fileTree(new File(sourceSet.getOutput().getResourcesDir(), "META-INF/spring"),
(tree) -> tree.filter((file) -> file.getName().endsWith(".imports")));
getSpringFactories().set(new File(sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories"));
this.classesDirs = sourceSet.getOutput().getClassesDirs();
}
@OutputFile
public File getOutputFile() {
return this.outputFile;
public abstract RegularFileProperty getOutputFile();
@InputFile
@PathSensitive(PathSensitivity.RELATIVE)
abstract RegularFileProperty getSpringFactories();
@Classpath
FileCollection getClasspath() {
return this.classpath;
}
public void setOutputFile(File outputFile) {
this.outputFile = outputFile;
Configuration testSliceMetadata = getProject().getConfigurations().maybeCreate("testSliceMetadata");
getProject().getArtifacts()
.add(testSliceMetadata.getName(), getProject().provider((Callable<File>) this::getOutputFile),
(artifact) -> artifact.builtBy(this));
@InputFiles
@PathSensitive(PathSensitivity.RELATIVE)
FileCollection getImportFiles() {
return this.importsFiles;
}
@Classpath
FileCollection getClassesDirs() {
return this.classesDirs;
}
@TaskAction
void documentTestSlices() throws IOException {
Properties testSlices = readTestSlices();
getOutputFile().getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(getOutputFile())) {
File outputFile = getOutputFile().getAsFile().get();
outputFile.getParentFile().mkdirs();
try (FileWriter writer = new FileWriter(outputFile)) {
testSlices.store(writer, null);
}
}
@ -104,15 +121,11 @@ public class TestSliceMetadata extends DefaultTask {
private Properties readTestSlices() throws IOException {
Properties testSlices = CollectionFactory.createSortedProperties(true);
try (URLClassLoader classLoader = new URLClassLoader(
StreamSupport.stream(this.sourceSet.getRuntimeClasspath().spliterator(), false)
.map(this::toURL)
.toArray(URL[]::new))) {
StreamSupport.stream(this.classpath.spliterator(), false).map(this::toURL).toArray(URL[]::new))) {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(classLoader);
Properties springFactories = readSpringFactories(
new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories"));
readTestSlicesDirectory(springFactories,
new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring/"));
for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) {
Properties springFactories = readSpringFactories(getSpringFactories().getAsFile().get());
readImportsFiles(springFactories, this.importsFiles);
for (File classesDir : this.classesDirs) {
addTestSlices(testSlices, classesDir, metadataReaderFactory, springFactories);
}
}
@ -120,18 +133,14 @@ public class TestSliceMetadata extends DefaultTask {
}
/**
* Reads files from the given directory and puts them in springFactories. The key is
* the file name, the value is the file contents, split by line, delimited with comma.
* This is done to mimic the spring.factories structure.
* Reads the given imports files and puts them in springFactories. The key is the file
* name, the value is the file contents, split by line, delimited with a comma. This
* is done to mimic the spring.factories structure.
* @param springFactories spring.factories parsed as properties
* @param directory directory to scan
* @param importsFiles the imports files to read
*/
private void readTestSlicesDirectory(Properties springFactories, File directory) {
File[] files = directory.listFiles((dir, name) -> name.endsWith(".imports"));
if (files == null) {
return;
}
for (File file : files) {
private void readImportsFiles(Properties springFactories, FileCollection importsFiles) {
for (File file : importsFiles.getFiles()) {
try {
List<String> lines = removeComments(Files.readAllLines(file.toPath()));
String fileNameWithoutExtension = file.getName()

View File

@ -2,8 +2,8 @@ require 'formula'
class SpringBoot < Formula
homepage 'https://spring.io/projects/spring-boot'
url '${repo}/org/springframework/boot/spring-boot-cli/${project.version}/spring-boot-cli-${project.version}-bin.tar.gz'
version '${project.version}'
url '${repo}/org/springframework/boot/spring-boot-cli/${version}/spring-boot-cli-${version}-bin.tar.gz'
version '${version}'
sha256 '${hash}'
head 'https://github.com/spring-projects/spring-boot.git', :branch => "main"

View File

@ -122,7 +122,7 @@ task xsdResources(type: Sync) {
}
prepareMavenBinaries {
versions "3.9.6", "3.6.3"
versions = [ "3.9.6", "3.6.3" ]
}
tasks.named("documentPluginGoals") {