Merge branch '2.7.x' into 3.0.x

This commit is contained in:
Phillip Webb
2023-02-21 23:15:40 -08:00
1890 changed files with 27173 additions and 21952 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -91,8 +91,9 @@ public class SpringBootExtension {
this::configureBuildInfoTask);
this.project.getPlugins().withType(JavaPlugin.class, (plugin) -> {
tasks.named(JavaPlugin.CLASSES_TASK_NAME).configure((task) -> task.dependsOn(bootBuildInfo));
bootBuildInfo.configure((buildInfo) -> buildInfo.getProperties().getArtifact()
.convention(this.project.provider(() -> determineArtifactBaseName())));
bootBuildInfo.configure((buildInfo) -> buildInfo.getProperties()
.getArtifact()
.convention(this.project.provider(() -> determineArtifactBaseName())));
});
if (configurer != null) {
bootBuildInfo.configure(configurer);
@@ -102,13 +103,18 @@ public class SpringBootExtension {
private void configureBuildInfoTask(BuildInfo task) {
task.setGroup(BasePlugin.BUILD_GROUP);
task.setDescription("Generates a META-INF/build-info.properties file.");
task.getDestinationDir().convention(this.project.getLayout()
task.getDestinationDir()
.convention(this.project.getLayout()
.dir(this.project.provider(() -> new File(determineMainSourceSetResourcesOutputDir(), "META-INF"))));
}
private File determineMainSourceSetResourcesOutputDir() {
return this.project.getExtensions().getByType(JavaPluginExtension.class).getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput().getResourcesDir();
return this.project.getExtensions()
.getByType(JavaPluginExtension.class)
.getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getOutput()
.getResourcesDir();
}
private String determineArtifactBaseName() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -49,10 +49,10 @@ final class ApplicationPluginAction implements PluginApplicationAction {
DistributionContainer distributions = project.getExtensions().getByType(DistributionContainer.class);
Distribution distribution = distributions.create("boot");
distribution.getDistributionBaseName()
.convention((project.provider(() -> javaApplication.getApplicationName() + "-boot")));
TaskProvider<CreateStartScripts> bootStartScripts = project.getTasks().register("bootStartScripts",
CreateStartScripts.class,
(task) -> configureCreateStartScripts(project, javaApplication, distribution, task));
.convention((project.provider(() -> javaApplication.getApplicationName() + "-boot")));
TaskProvider<CreateStartScripts> bootStartScripts = project.getTasks()
.register("bootStartScripts", CreateStartScripts.class,
(task) -> configureCreateStartScripts(project, javaApplication, distribution, task));
CopySpec binCopySpec = project.copySpec().into("bin").from(bootStartScripts);
binCopySpec.setFileMode(0755);
distribution.getContents().with(binCopySpec);
@@ -61,19 +61,19 @@ final class ApplicationPluginAction implements PluginApplicationAction {
private void configureCreateStartScripts(Project project, JavaApplication javaApplication,
Distribution distribution, CreateStartScripts createStartScripts) {
createStartScripts
.setDescription("Generates OS-specific start scripts to run the project as a Spring Boot application.");
.setDescription("Generates OS-specific start scripts to run the project as a Spring Boot application.");
((TemplateBasedScriptGenerator) createStartScripts.getUnixStartScriptGenerator())
.setTemplate(project.getResources().getText().fromString(loadResource("/unixStartScript.txt")));
.setTemplate(project.getResources().getText().fromString(loadResource("/unixStartScript.txt")));
((TemplateBasedScriptGenerator) createStartScripts.getWindowsStartScriptGenerator())
.setTemplate(project.getResources().getText().fromString(loadResource("/windowsStartScript.txt")));
.setTemplate(project.getResources().getText().fromString(loadResource("/windowsStartScript.txt")));
project.getConfigurations().all((configuration) -> {
if ("bootArchives".equals(configuration.getName())) {
distribution.getContents().with(artifactFilesToLibCopySpec(project, configuration));
createStartScripts.setClasspath(configuration.getArtifacts().getFiles());
}
});
createStartScripts.getConventionMapping().map("outputDir",
() -> new File(project.getBuildDir(), "bootScripts"));
createStartScripts.getConventionMapping()
.map("outputDir", () -> new File(project.getBuildDir(), "bootScripts"));
createStartScripts.getConventionMapping().map("applicationName", javaApplication::getApplicationName);
createStartScripts.getConventionMapping().map("defaultJvmOpts", javaApplication::getApplicationDefaultJvmArgs);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2019 the original author or authors.
* Copyright 2012-2023 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,8 +32,9 @@ final class DependencyManagementPluginAction implements PluginApplicationAction
@Override
public void execute(Project project) {
project.getExtensions().findByType(DependencyManagementExtension.class)
.imports((importsHandler) -> importsHandler.mavenBom(SpringBootPlugin.BOM_COORDINATES));
project.getExtensions()
.findByType(DependencyManagementExtension.class)
.imports((importsHandler) -> importsHandler.mavenBom(SpringBootPlugin.BOM_COORDINATES));
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -91,36 +91,41 @@ final class JavaPluginAction implements PluginApplicationAction {
}
private void classifyJarTask(Project project) {
project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class)
.configure((task) -> task.getArchiveClassifier().convention("plain"));
project.getTasks()
.named(JavaPlugin.JAR_TASK_NAME, Jar.class)
.configure((task) -> task.getArchiveClassifier().convention("plain"));
}
private void configureBuildTask(Project project) {
project.getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME)
.configure((task) -> task.dependsOn(this.singlePublishedArtifact));
project.getTasks()
.named(BasePlugin.ASSEMBLE_TASK_NAME)
.configure((task) -> task.dependsOn(this.singlePublishedArtifact));
}
private TaskProvider<ResolveMainClassName> configureResolveMainClassNameTask(Project project) {
return project.getTasks().register(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME,
ResolveMainClassName.class, (resolveMainClassName) -> {
ExtensionContainer extensions = project.getExtensions();
resolveMainClassName.setDescription("Resolves the name of the application's main class.");
resolveMainClassName.setGroup(BasePlugin.BUILD_GROUP);
Callable<FileCollection> classpath = () -> project.getExtensions()
.getByType(SourceSetContainer.class).getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput();
resolveMainClassName.setClasspath(classpath);
resolveMainClassName.getConfiguredMainClassName().convention(project.provider(() -> {
String javaApplicationMainClass = getJavaApplicationMainClass(extensions);
if (javaApplicationMainClass != null) {
return javaApplicationMainClass;
}
SpringBootExtension springBootExtension = project.getExtensions()
return project.getTasks()
.register(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class,
(resolveMainClassName) -> {
ExtensionContainer extensions = project.getExtensions();
resolveMainClassName.setDescription("Resolves the name of the application's main class.");
resolveMainClassName.setGroup(BasePlugin.BUILD_GROUP);
Callable<FileCollection> classpath = () -> project.getExtensions()
.getByType(SourceSetContainer.class)
.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getOutput();
resolveMainClassName.setClasspath(classpath);
resolveMainClassName.getConfiguredMainClassName().convention(project.provider(() -> {
String javaApplicationMainClass = getJavaApplicationMainClass(extensions);
if (javaApplicationMainClass != null) {
return javaApplicationMainClass;
}
SpringBootExtension springBootExtension = project.getExtensions()
.findByType(SpringBootExtension.class);
return springBootExtension.getMainClass().getOrNull();
}));
resolveMainClassName.getOutputFile()
return springBootExtension.getMainClass().getOrNull();
}));
resolveMainClassName.getOutputFile()
.set(project.getLayout().getBuildDirectory().file("resolvedMainClassName"));
});
});
}
private static String getJavaApplicationMainClass(ExtensionContainer extensions) {
@@ -134,24 +139,26 @@ final class JavaPluginAction implements PluginApplicationAction {
private TaskProvider<BootJar> configureBootJarTask(Project project,
TaskProvider<ResolveMainClassName> resolveMainClassName) {
SourceSet mainSourceSet = javaPluginExtension(project).getSourceSets()
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
Configuration developmentOnly = project.getConfigurations()
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
Configuration productionRuntimeClasspath = project.getConfigurations()
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
Callable<FileCollection> classpath = () -> mainSourceSet.getRuntimeClasspath()
.minus((developmentOnly.minus(productionRuntimeClasspath))).filter(new JarTypeFileSpec());
.minus((developmentOnly.minus(productionRuntimeClasspath)))
.filter(new JarTypeFileSpec());
return project.getTasks().register(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class, (bootJar) -> {
bootJar.setDescription(
"Assembles an executable jar archive containing the main classes and their dependencies.");
bootJar.setGroup(BasePlugin.BUILD_GROUP);
bootJar.classpath(classpath);
Provider<String> manifestStartClass = project
.provider(() -> (String) bootJar.getManifest().getAttributes().get("Start-Class"));
bootJar.getMainClass().convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
.provider(() -> (String) bootJar.getManifest().getAttributes().get("Start-Class"));
bootJar.getMainClass()
.convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
bootJar.getTargetJavaVersion()
.set(project.provider(() -> javaPluginExtension(project).getTargetCompatibility()));
.set(project.provider(() -> javaPluginExtension(project).getTargetCompatibility()));
});
}
@@ -169,7 +176,9 @@ final class JavaPluginAction implements PluginApplicationAction {
private void configureBootRunTask(Project project, TaskProvider<ResolveMainClassName> resolveMainClassName) {
Callable<FileCollection> classpath = () -> javaPluginExtension(project).getSourceSets()
.findByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath().filter(new JarTypeFileSpec());
.findByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getRuntimeClasspath()
.filter(new JarTypeFileSpec());
project.getTasks().register("bootRun", BootRun.class, (run) -> {
run.setDescription("Runs this project as a Spring Boot application.");
run.setGroup(ApplicationPlugin.APPLICATION_GROUP);
@@ -215,27 +224,32 @@ final class JavaPluginAction implements PluginApplicationAction {
}
private void configureAdditionalMetadataLocations(Project project) {
project.afterEvaluate((evaluated) -> evaluated.getTasks().withType(JavaCompile.class)
.configureEach(this::configureAdditionalMetadataLocations));
project.afterEvaluate((evaluated) -> evaluated.getTasks()
.withType(JavaCompile.class)
.configureEach(this::configureAdditionalMetadataLocations));
}
private void configureAdditionalMetadataLocations(JavaCompile compile) {
SourceSetContainer sourceSets = compile.getProject().getExtensions().getByType(JavaPluginExtension.class)
.getSourceSets();
sourceSets.stream().filter((candidate) -> candidate.getCompileJavaTaskName().equals(compile.getName()))
.map((match) -> match.getResources().getSrcDirs()).findFirst()
.ifPresent((locations) -> compile.doFirst(new AdditionalMetadataLocationsConfigurer(locations)));
SourceSetContainer sourceSets = compile.getProject()
.getExtensions()
.getByType(JavaPluginExtension.class)
.getSourceSets();
sourceSets.stream()
.filter((candidate) -> candidate.getCompileJavaTaskName().equals(compile.getName()))
.map((match) -> match.getResources().getSrcDirs())
.findFirst()
.ifPresent((locations) -> compile.doFirst(new AdditionalMetadataLocationsConfigurer(locations)));
}
private void configureDevelopmentOnlyConfiguration(Project project) {
Configuration developmentOnly = project.getConfigurations()
.create(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
.create(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
developmentOnly
.setDescription("Configuration for development-only dependencies such as Spring Boot's DevTools.");
.setDescription("Configuration for development-only dependencies such as Spring Boot's DevTools.");
Configuration runtimeClasspath = project.getConfigurations()
.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
Configuration productionRuntimeClasspath = project.getConfigurations()
.create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
.create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
AttributeContainer attributes = productionRuntimeClasspath.getAttributes();
ObjectFactory objectFactory = project.getObjects();
attributes.attribute(Usage.USAGE_ATTRIBUTE, objectFactory.named(Usage.class, Usage.JAVA_RUNTIME));
@@ -275,14 +289,16 @@ final class JavaPluginAction implements PluginApplicationAction {
private boolean hasConfigurationProcessorOnClasspath(JavaCompile compile) {
Set<File> files = (compile.getOptions().getAnnotationProcessorPath() != null)
? compile.getOptions().getAnnotationProcessorPath().getFiles() : compile.getClasspath().getFiles();
return files.stream().map(File::getName)
.anyMatch((name) -> name.startsWith("spring-boot-configuration-processor"));
return files.stream()
.map(File::getName)
.anyMatch((name) -> name.startsWith("spring-boot-configuration-processor"));
}
private void configureAdditionalMetadataLocations(JavaCompile compile) {
compile.getOptions().getCompilerArgs()
.add("-Aorg.springframework.boot.configurationprocessor.additionalMetadataLocations="
+ StringUtils.collectionToCommaDelimitedString(this.locations));
compile.getOptions()
.getCompilerArgs()
.add("-Aorg.springframework.boot.configurationprocessor.additionalMetadataLocations="
+ StringUtils.collectionToCommaDelimitedString(this.locations));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -47,8 +47,9 @@ class KotlinPluginAction implements PluginApplicationAction {
}
private void enableJavaParametersOption(Project project) {
project.getTasks().withType(KotlinCompile.class)
.configureEach((compile) -> compile.getKotlinOptions().setJavaParameters(true));
project.getTasks()
.withType(KotlinCompile.class)
.configureEach((compile) -> compile.getKotlinOptions().setJavaParameters(true));
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -70,15 +70,16 @@ class NativeImagePluginAction implements PluginApplicationAction {
private void configureMainNativeBinaryClasspath(Project project, SourceSetContainer sourceSets,
GraalVMExtension graalVmExtension) {
FileCollection runtimeClasspath = sourceSets.getByName(SpringBootAotPlugin.AOT_SOURCE_SET_NAME)
.getRuntimeClasspath();
.getRuntimeClasspath();
graalVmExtension.getBinaries().getByName(NativeImagePlugin.NATIVE_MAIN_EXTENSION).classpath(runtimeClasspath);
Configuration nativeImageClasspath = project.getConfigurations().getByName("nativeImageClasspath");
nativeImageClasspath.setExtendsFrom(removeDevelopmentOnly(nativeImageClasspath.getExtendsFrom()));
}
private Iterable<Configuration> removeDevelopmentOnly(Set<Configuration> configurations) {
return configurations.stream().filter(this::isNotDevelopmentOnly)
.collect(Collectors.toCollection(LinkedHashSet::new));
return configurations.stream()
.filter(this::isNotDevelopmentOnly)
.collect(Collectors.toCollection(LinkedHashSet::new));
}
private boolean isNotDevelopmentOnly(Configuration configuration) {
@@ -88,7 +89,7 @@ class NativeImagePluginAction implements PluginApplicationAction {
private void configureTestNativeBinaryClasspath(Project project, SourceSetContainer sourceSets,
GraalVMExtension graalVmExtension) {
FileCollection runtimeClasspath = sourceSets.getByName(SpringBootAotPlugin.AOT_TEST_SOURCE_SET_NAME)
.getRuntimeClasspath();
.getRuntimeClasspath();
graalVmExtension.getBinaries().getByName(NativeImagePlugin.NATIVE_TEST_EXTENSION).classpath(runtimeClasspath);
}
@@ -109,21 +110,23 @@ class NativeImagePluginAction implements PluginApplicationAction {
private void configureGraalVmReachabilityExtension(GraalVMExtension graalVmExtension) {
GraalVMReachabilityMetadataRepositoryExtension extension = ((ExtensionAware) graalVmExtension).getExtensions()
.getByType(GraalVMReachabilityMetadataRepositoryExtension.class);
.getByType(GraalVMReachabilityMetadataRepositoryExtension.class);
extension.getEnabled().set(true);
}
private void copyReachabilityMetadataToBootJar(Project project) {
project.getTasks().named(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class)
.configure((bootJar) -> bootJar.from(project.getTasks().named("collectReachabilityMetadata")));
project.getTasks()
.named(SpringBootPlugin.BOOT_JAR_TASK_NAME, BootJar.class)
.configure((bootJar) -> bootJar.from(project.getTasks().named("collectReachabilityMetadata")));
}
private void configureBootBuildImageToProduceANativeImage(Project project) {
project.getTasks().named(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class)
.configure((bootBuildImage) -> {
bootBuildImage.getBuilder().convention("paketobuildpacks/builder:tiny");
bootBuildImage.getEnvironment().put("BP_NATIVE_IMAGE", "true");
});
project.getTasks()
.named(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class)
.configure((bootBuildImage) -> {
bootBuildImage.getBuilder().convention("paketobuildpacks/builder:tiny");
bootBuildImage.getEnvironment().put("BP_NATIVE_IMAGE", "true");
});
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -130,8 +130,13 @@ public class ResolveMainClassName extends DefaultTask {
if (configuredMainClass != null) {
return configuredMainClass;
}
return getClasspath().filter(File::isDirectory).getFiles().stream().map(this::findMainClass)
.filter(Objects::nonNull).findFirst().orElse("");
return getClasspath().filter(File::isDirectory)
.getFiles()
.stream()
.map(this::findMainClass)
.filter(Objects::nonNull)
.findFirst()
.orElse("");
}
private String findMainClass(File file) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -90,17 +90,18 @@ public class SpringBootAotPlugin implements Plugin<Project> {
SourceSetContainer sourceSets = javaPluginExtension.getSourceSets();
return sourceSets.create(newSourceSetName, (sourceSet) -> {
existingSourceSet.setRuntimeClasspath(existingSourceSet.getRuntimeClasspath().plus(sourceSet.getOutput()));
project.getConfigurations().getByName(sourceSet.getCompileClasspathConfigurationName())
.attributes((attributes) -> {
configureClassesAndResourcesLibraryElementsAttribute(project, attributes);
configureJavaRuntimeUsageAttribute(project, attributes);
});
project.getConfigurations()
.getByName(sourceSet.getCompileClasspathConfigurationName())
.attributes((attributes) -> {
configureClassesAndResourcesLibraryElementsAttribute(project, attributes);
configureJavaRuntimeUsageAttribute(project, attributes);
});
});
}
private void configureClassesAndResourcesLibraryElementsAttribute(Project project, AttributeContainer attributes) {
LibraryElements classesAndResources = project.getObjects().named(LibraryElements.class,
LibraryElements.CLASSES_AND_RESOURCES);
LibraryElements classesAndResources = project.getObjects()
.named(LibraryElements.class, LibraryElements.CLASSES_AND_RESOURCES);
attributes.attribute(LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE, classesAndResources);
}
@@ -111,21 +112,22 @@ public class SpringBootAotPlugin implements Plugin<Project> {
private void registerProcessAotTask(Project project, SourceSet aotSourceSet, SourceSet mainSourceSet) {
TaskProvider<ResolveMainClassName> resolveMainClassName = project.getTasks()
.named(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class);
.named(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class);
Configuration aotClasspath = createAotProcessingClasspath(project, PROCESS_AOT_TASK_NAME, mainSourceSet);
project.getDependencies().add(aotClasspath.getName(), project.files(mainSourceSet.getOutput()));
Configuration compileClasspath = project.getConfigurations()
.getByName(aotSourceSet.getCompileClasspathConfigurationName());
.getByName(aotSourceSet.getCompileClasspathConfigurationName());
compileClasspath.extendsFrom(aotClasspath);
Provider<Directory> resourcesOutput = project.getLayout().getBuildDirectory()
.dir("generated/" + aotSourceSet.getName() + "Resources");
TaskProvider<ProcessAot> processAot = project.getTasks().register(PROCESS_AOT_TASK_NAME, ProcessAot.class,
(task) -> {
configureAotTask(project, aotSourceSet, task, mainSourceSet, resourcesOutput);
task.getApplicationMainClass()
.set(resolveMainClassName.flatMap(ResolveMainClassName::readMainClassName));
task.setClasspath(aotClasspath);
});
Provider<Directory> resourcesOutput = project.getLayout()
.getBuildDirectory()
.dir("generated/" + aotSourceSet.getName() + "Resources");
TaskProvider<ProcessAot> processAot = project.getTasks()
.register(PROCESS_AOT_TASK_NAME, ProcessAot.class, (task) -> {
configureAotTask(project, aotSourceSet, task, mainSourceSet, resourcesOutput);
task.getApplicationMainClass()
.set(resolveMainClassName.flatMap(ResolveMainClassName::readMainClassName));
task.setClasspath(aotClasspath);
});
aotSourceSet.getJava().srcDir(processAot.map(ProcessAot::getSourcesOutput));
aotSourceSet.getResources().srcDir(resourcesOutput);
ConfigurableFileCollection classesOutputFiles = project.files(processAot.map(ProcessAot::getClassesOutput));
@@ -137,10 +139,10 @@ public class SpringBootAotPlugin implements Plugin<Project> {
private void configureAotTask(Project project, SourceSet sourceSet, AbstractAot task, SourceSet inputSourceSet,
Provider<Directory> resourcesOutput) {
task.getSourcesOutput()
.set(project.getLayout().getBuildDirectory().dir("generated/" + sourceSet.getName() + "Sources"));
.set(project.getLayout().getBuildDirectory().dir("generated/" + sourceSet.getName() + "Sources"));
task.getResourcesOutput().set(resourcesOutput);
task.getClassesOutput()
.set(project.getLayout().getBuildDirectory().dir("generated/" + sourceSet.getName() + "Classes"));
.set(project.getLayout().getBuildDirectory().dir("generated/" + sourceSet.getName() + "Classes"));
task.getGroupId().set(project.provider(() -> String.valueOf(project.getGroup())));
task.getArtifactId().set(project.provider(() -> project.getName()));
}
@@ -148,7 +150,7 @@ public class SpringBootAotPlugin implements Plugin<Project> {
@SuppressWarnings("unchecked")
private Configuration createAotProcessingClasspath(Project project, String taskName, SourceSet inputSourceSet) {
Configuration base = project.getConfigurations()
.getByName(inputSourceSet.getRuntimeClasspathConfigurationName());
.getByName(inputSourceSet.getRuntimeClasspathConfigurationName());
Configuration aotClasspath = project.getConfigurations().create(taskName + "Classpath", (classpath) -> {
classpath.setCanBeConsumed(false);
classpath.setCanBeResolved(true);
@@ -166,8 +168,9 @@ public class SpringBootAotPlugin implements Plugin<Project> {
private void configureDependsOn(Project project, SourceSet aotSourceSet,
TaskProvider<? extends AbstractAot> processAot) {
project.getTasks().named(aotSourceSet.getProcessResourcesTaskName())
.configure((processResources) -> processResources.dependsOn(processAot));
project.getTasks()
.named(aotSourceSet.getProcessResourcesTaskName())
.configure((processResources) -> processResources.dependsOn(processAot));
}
private void registerProcessTestAotTask(Project project, SourceSet mainSourceSet, SourceSet aotTestSourceSet,
@@ -175,22 +178,23 @@ public class SpringBootAotPlugin implements Plugin<Project> {
Configuration aotClasspath = createAotProcessingClasspath(project, PROCESS_TEST_AOT_TASK_NAME, testSourceSet);
addJUnitPlatformLauncherDependency(project, aotClasspath);
Configuration compileClasspath = project.getConfigurations()
.getByName(aotTestSourceSet.getCompileClasspathConfigurationName());
.getByName(aotTestSourceSet.getCompileClasspathConfigurationName());
compileClasspath.extendsFrom(aotClasspath);
Provider<Directory> resourcesOutput = project.getLayout().getBuildDirectory()
.dir("generated/" + aotTestSourceSet.getName() + "Resources");
TaskProvider<ProcessTestAot> processTestAot = project.getTasks().register(PROCESS_TEST_AOT_TASK_NAME,
ProcessTestAot.class, (task) -> {
configureAotTask(project, aotTestSourceSet, task, testSourceSet, resourcesOutput);
task.setClasspath(aotClasspath);
task.setClasspathRoots(testSourceSet.getOutput());
});
Provider<Directory> resourcesOutput = project.getLayout()
.getBuildDirectory()
.dir("generated/" + aotTestSourceSet.getName() + "Resources");
TaskProvider<ProcessTestAot> processTestAot = project.getTasks()
.register(PROCESS_TEST_AOT_TASK_NAME, ProcessTestAot.class, (task) -> {
configureAotTask(project, aotTestSourceSet, task, testSourceSet, resourcesOutput);
task.setClasspath(aotClasspath);
task.setClasspathRoots(testSourceSet.getOutput());
});
aotTestSourceSet.getJava().srcDir(processTestAot.map(ProcessTestAot::getSourcesOutput));
aotTestSourceSet.getResources().srcDir(resourcesOutput);
project.getDependencies().add(aotClasspath.getName(), project.files(mainSourceSet.getOutput()));
project.getDependencies().add(aotClasspath.getName(), project.files(testSourceSet.getOutput()));
ConfigurableFileCollection classesOutputFiles = project
.files(processTestAot.map(ProcessTestAot::getClassesOutput));
.files(processTestAot.map(ProcessTestAot::getClassesOutput));
testSourceSet.setRuntimeClasspath(testSourceSet.getRuntimeClasspath().plus(classesOutputFiles));
project.getDependencies().add(aotTestSourceSet.getImplementationConfigurationName(), classesOutputFiles);
configureDependsOn(project, aotTestSourceSet, processTestAot);
@@ -199,7 +203,7 @@ public class SpringBootAotPlugin implements Plugin<Project> {
private void addJUnitPlatformLauncherDependency(Project project, Configuration configuration) {
DependencyHandler dependencyHandler = project.getDependencies();
Dependency springBootDependencies = dependencyHandler
.create(dependencyHandler.platform(SpringBootPlugin.BOM_COORDINATES));
.create(dependencyHandler.platform(SpringBootPlugin.BOM_COORDINATES));
DependencySet dependencies = configuration.getDependencies();
dependencies.add(springBootDependencies);
dependencies.add(dependencyHandler.create("org.junit.platform:junit-platform-launcher"));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -64,36 +64,40 @@ class WarPluginAction implements PluginApplicationAction {
}
private void classifyWarTask(Project project) {
project.getTasks().named(WarPlugin.WAR_TASK_NAME, War.class)
.configure((war) -> war.getArchiveClassifier().convention("plain"));
project.getTasks()
.named(WarPlugin.WAR_TASK_NAME, War.class)
.configure((war) -> war.getArchiveClassifier().convention("plain"));
}
private TaskProvider<BootWar> configureBootWarTask(Project project) {
Configuration developmentOnly = project.getConfigurations()
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
Configuration productionRuntimeClasspath = project.getConfigurations()
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
Callable<FileCollection> classpath = () -> project.getExtensions().getByType(SourceSetContainer.class)
.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath()
.minus(providedRuntimeConfiguration(project)).minus((developmentOnly.minus(productionRuntimeClasspath)))
.filter(new JarTypeFileSpec());
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_CONFIGURATION_NAME);
Callable<FileCollection> classpath = () -> project.getExtensions()
.getByType(SourceSetContainer.class)
.getByName(SourceSet.MAIN_SOURCE_SET_NAME)
.getRuntimeClasspath()
.minus(providedRuntimeConfiguration(project))
.minus((developmentOnly.minus(productionRuntimeClasspath)))
.filter(new JarTypeFileSpec());
TaskProvider<ResolveMainClassName> resolveMainClassName = project.getTasks()
.named(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class);
TaskProvider<BootWar> bootWarProvider = project.getTasks().register(SpringBootPlugin.BOOT_WAR_TASK_NAME,
BootWar.class, (bootWar) -> {
bootWar.setGroup(BasePlugin.BUILD_GROUP);
bootWar.setDescription("Assembles an executable war archive containing webapp"
+ " content, and the main classes and their dependencies.");
bootWar.providedClasspath(providedRuntimeConfiguration(project));
bootWar.setClasspath(classpath);
Provider<String> manifestStartClass = project
.provider(() -> (String) bootWar.getManifest().getAttributes().get("Start-Class"));
bootWar.getMainClass()
.convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
bootWar.getTargetJavaVersion()
.set(project.provider(() -> javaPluginExtension(project).getTargetCompatibility()));
});
.named(SpringBootPlugin.RESOLVE_MAIN_CLASS_NAME_TASK_NAME, ResolveMainClassName.class);
TaskProvider<BootWar> bootWarProvider = project.getTasks()
.register(SpringBootPlugin.BOOT_WAR_TASK_NAME, BootWar.class, (bootWar) -> {
bootWar.setGroup(BasePlugin.BUILD_GROUP);
bootWar.setDescription("Assembles an executable war archive containing webapp"
+ " content, and the main classes and their dependencies.");
bootWar.providedClasspath(providedRuntimeConfiguration(project));
bootWar.setClasspath(classpath);
Provider<String> manifestStartClass = project
.provider(() -> (String) bootWar.getManifest().getAttributes().get("Start-Class"));
bootWar.getMainClass()
.convention(resolveMainClassName.flatMap((resolver) -> manifestStartClass.isPresent()
? manifestStartClass : resolveMainClassName.get().readMainClassName()));
bootWar.getTargetJavaVersion()
.set(project.provider(() -> javaPluginExtension(project).getTargetCompatibility()));
});
bootWarProvider.map(War::getClasspath);
return bootWarProvider;
}
@@ -104,8 +108,9 @@ class WarPluginAction implements PluginApplicationAction {
}
private void configureBootBuildImageTask(Project project, TaskProvider<BootWar> bootWar) {
project.getTasks().named(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class)
.configure((buildImage) -> buildImage.getArchiveFile().set(bootWar.get().getArchiveFile()));
project.getTasks()
.named(SpringBootPlugin.BOOT_BUILD_IMAGE_TASK_NAME, BootBuildImage.class)
.configure((buildImage) -> buildImage.getArchiveFile().set(bootWar.get().getArchiveFile()));
}
private void configureArtifactPublication(TaskProvider<BootWar> bootWar) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -78,8 +78,11 @@ public class ProcessTestAot extends AbstractAot {
@TaskAction
public void exec() {
List<String> args = new ArrayList<>();
args.add(getClasspathRoots().getFiles().stream().filter(File::exists).map(File::getAbsolutePath)
.collect(Collectors.joining(File.pathSeparator)));
args.add(getClasspathRoots().getFiles()
.stream()
.filter(File::exists)
.map(File::getAbsolutePath)
.collect(Collectors.joining(File.pathSeparator)));
args.addAll(processorArgs());
setArgs(args);
super.exec();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -71,7 +71,7 @@ public abstract class BuildInfo extends DefaultTask {
this.properties.getNameIfNotExcluded(), this.properties.getTimeIfNotExcluded(),
this.properties.getAdditionalIfNotExcluded());
new BuildPropertiesWriter(new File(getDestinationDir().get().getAsFile(), "build-info.properties"))
.writeBuildProperties(details);
.writeBuildProperties(details);
}
catch (IOException ex) {
throw new TaskExecutionException(this, ex);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -56,7 +56,7 @@ public abstract class BuildInfoProperties implements Serializable {
getGroup().convention(project.provider(() -> project.getGroup().toString()));
getVersion().convention(project.provider(() -> project.getVersion().toString()));
getArtifact()
.convention(project.provider(() -> project.findProperty("archivesBaseName")).map(Object::toString));
.convention(project.provider(() -> project.findProperty("archivesBaseName")).map(Object::toString));
getName().convention(project.provider(project::getName));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -78,8 +78,9 @@ public abstract class BootBuildImage extends DefaultTask {
public BootBuildImage() {
this.projectName = getProject().getName();
Project project = getProject();
Property<String> projectVersion = project.getObjects().property(String.class)
.convention(project.provider(() -> project.getVersion().toString()));
Property<String> projectVersion = project.getObjects()
.property(String.class)
.convention(project.provider(() -> project.getVersion().toString()));
getImageName().convention(project.provider(() -> {
ImageName imageName = ImageName.of(this.projectName);
if ("unspecified".equals(projectVersion.get())) {

View File

@@ -165,7 +165,7 @@ public abstract class BootWar extends War implements BootArchive {
public void providedClasspath(Object... classpath) {
FileCollection existingClasspath = this.providedClasspath;
this.providedClasspath = getProject()
.files((existingClasspath != null) ? existingClasspath : Collections.emptyList(), classpath);
.files((existingClasspath != null) ? existingClasspath : Collections.emptyList(), classpath);
}
/**

View File

@@ -74,11 +74,11 @@ import org.springframework.util.StringUtils;
class BootZipCopyAction implements CopyAction {
static final long CONSTANT_TIME_FOR_ZIP_ENTRIES = new GregorianCalendar(1980, Calendar.FEBRUARY, 1, 0, 0, 0)
.getTimeInMillis();
.getTimeInMillis();
private static final Pattern REACHABILITY_METADATA_PROPERTIES_LOCATION_PATTERN = Pattern
.compile(ReachabilityMetadataProperties.REACHABILITY_METADATA_PROPERTIES_LOCATION_TEMPLATE.formatted(".*",
".*", ".*"));
.compile(ReachabilityMetadataProperties.REACHABILITY_METADATA_PROPERTIES_LOCATION_TEMPLATE.formatted(".*", ".*",
".*"));
private final File output;
@@ -352,14 +352,14 @@ class BootZipCopyAction implements CopyAction {
Set<String> excludes = new LinkedHashSet<>();
for (Map.Entry<String, FileCopyDetails> entry : this.writtenLibraries.entrySet()) {
DependencyDescriptor descriptor = BootZipCopyAction.this.resolvedDependencies
.find(entry.getValue().getFile());
.find(entry.getValue().getFile());
LibraryCoordinates coordinates = (descriptor != null) ? descriptor.getCoordinates() : null;
FileCopyDetails propertiesFile = (coordinates != null) ? this.reachabilityMetadataProperties
.get(ReachabilityMetadataProperties.getLocation(coordinates)) : null;
.get(ReachabilityMetadataProperties.getLocation(coordinates)) : null;
if (propertiesFile != null) {
try (InputStream inputStream = propertiesFile.open()) {
ReachabilityMetadataProperties properties = ReachabilityMetadataProperties
.fromInputStream(inputStream);
.fromInputStream(inputStream);
if (properties.isOverridden()) {
excludes.add(entry.getKey());
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -309,13 +309,15 @@ public abstract class LayeredSpec {
ContentSelector<Library> asLibrarySelector(Function<String, ContentFilter<Library>> filterFactory) {
Layer layer = new Layer(getIntoLayer());
List<ContentFilter<Library>> includeFilters = getIncludes().stream().map(filterFactory)
.collect(Collectors.toCollection(ArrayList::new));
List<ContentFilter<Library>> includeFilters = getIncludes().stream()
.map(filterFactory)
.collect(Collectors.toCollection(ArrayList::new));
if (this.includeProjectDependencies) {
includeFilters.add(Library::isLocal);
}
List<ContentFilter<Library>> excludeFilters = getExcludes().stream().map(filterFactory)
.collect(Collectors.toCollection(ArrayList::new));
List<ContentFilter<Library>> excludeFilters = getExcludes().stream()
.map(filterFactory)
.collect(Collectors.toCollection(ArrayList::new));
if (this.excludeProjectDependencies) {
excludeFilters.add(Library::isLocal);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -50,8 +50,11 @@ class ResolvedDependencies {
}
void processConfiguration(Project project, Configuration configuration) {
Set<String> localProjectIds = project.getRootProject().getAllprojects().stream().map(this::projectId)
.collect(Collectors.toSet());
Set<String> localProjectIds = project.getRootProject()
.getAllprojects()
.stream()
.map(this::projectId)
.collect(Collectors.toSet());
this.configurationDependencies.put(configuration,
new ResolvedConfigurationDependencies(localProjectIds, configuration.getResolvedConfiguration()));
}
@@ -83,7 +86,7 @@ class ResolvedDependencies {
for (ResolvedArtifact resolvedArtifact : lenientConfiguration.getArtifacts()) {
ModuleVersionIdentifier id = resolvedArtifact.getModuleVersion().getId();
boolean projectDependency = projectDependencyIds
.contains(id.getGroup() + ":" + id.getName() + ":" + id.getVersion());
.contains(id.getGroup() + ":" + id.getName() + ":" + id.getVersion());
this.dependencies.put(resolvedArtifact.getFile(), new DependencyDescriptor(
new ModuleVersionIdentifierLibraryCoordinates(id), projectDependency));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -47,12 +47,14 @@ class TaskConfigurationAvoidanceTests {
@ArchTest
void noApisThatCauseEagerTaskConfigurationShouldBeCalled(JavaClasses classes) {
ProhibitedMethods prohibited = new ProhibitedMethods();
prohibited.on(TaskContainer.class).methodsNamed("create", "findByPath, getByPath").method("withType",
Class.class, Action.class);
prohibited.on(TaskContainer.class)
.methodsNamed("create", "findByPath, getByPath")
.method("withType", Class.class, Action.class);
prohibited.on(TaskCollection.class).methodsNamed("findByName", "getByName");
ArchRuleDefinition.noClasses().should()
.callMethodWhere(DescribedPredicate.describe("it would cause eager task configuration", prohibited))
.check(classes);
ArchRuleDefinition.noClasses()
.should()
.callMethodWhere(DescribedPredicate.describe("it would cause eager task configuration", prohibited))
.check(classes);
}
static class DoNotIncludeTests implements ImportOption {
@@ -99,7 +101,7 @@ class TaskConfigurationAvoidanceTests {
private ProhibitedConfigurer method(String name, Class<?>... parameterTypes) {
ProhibitedMethods.this.prohibited
.add(new ProhibitMethod(this.type, name, Arrays.asList(parameterTypes)));
.add(new ProhibitMethod(this.type, name, Arrays.asList(parameterTypes)));
return this;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,13 +44,13 @@ class IntegratingWithActuatorDocumentationTests {
void basicBuildInfo() {
this.gradleBuild.script("src/docs/gradle/integrating-with-actuator/build-info-basic").build("bootBuildInfo");
assertThat(new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties"))
.isFile();
.isFile();
}
@TestTemplate
void buildInfoCustomValues() {
this.gradleBuild.script("src/docs/gradle/integrating-with-actuator/build-info-custom-values")
.build("bootBuildInfo");
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = buildInfoProperties(file);
@@ -64,7 +64,7 @@ class IntegratingWithActuatorDocumentationTests {
@TestTemplate
void buildInfoAdditional() {
this.gradleBuild.script("src/docs/gradle/integrating-with-actuator/build-info-additional")
.build("bootBuildInfo");
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = buildInfoProperties(file);
@@ -75,7 +75,7 @@ class IntegratingWithActuatorDocumentationTests {
@TestTemplate
void buildInfoExcludeTime() {
this.gradleBuild.script("src/docs/gradle/integrating-with-actuator/build-info-exclude-time")
.build("bootBuildInfo");
.build("bootBuildInfo");
File file = new File(this.gradleBuild.getProjectDir(), "build/resources/main/META-INF/build-info.properties");
assertThat(file).isFile();
Properties properties = buildInfoProperties(file);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,14 +44,16 @@ class ManagingDependenciesDocumentationTests {
@TestTemplate
void customManagedVersions() {
assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/custom-version").build("slf4jVersion")
.getOutput()).contains("1.7.20");
assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/custom-version")
.build("slf4jVersion")
.getOutput()).contains("1.7.20");
}
@TestTemplate
void dependencyManagementInIsolation() {
assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/configure-bom")
.build("dependencyManagement").getOutput()).contains("org.springframework.boot:spring-boot-starter ");
.build("dependencyManagement")
.getOutput()).contains("org.springframework.boot:spring-boot-starter ");
}
@TestTemplate
@@ -59,21 +61,23 @@ class ManagingDependenciesDocumentationTests {
assumingThat(this.gradleBuild.getDsl() == Dsl.KOTLIN,
() -> assertThat(
this.gradleBuild.script("src/docs/gradle/managing-dependencies/configure-bom-with-plugins")
.build("dependencyManagement").getOutput())
.contains("org.springframework.boot:spring-boot-starter TEST-SNAPSHOT"));
.build("dependencyManagement")
.getOutput())
.contains("org.springframework.boot:spring-boot-starter TEST-SNAPSHOT"));
}
@TestTemplate
void configurePlatform() {
assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/configure-platform")
.build("dependencies", "--configuration", "compileClasspath").getOutput())
.contains("org.springframework.boot:spring-boot-starter ");
.build("dependencies", "--configuration", "compileClasspath")
.getOutput()).contains("org.springframework.boot:spring-boot-starter ");
}
@TestTemplate
void customManagedVersionsWithPlatform() {
assertThat(this.gradleBuild.script("src/docs/gradle/managing-dependencies/custom-version-with-platform")
.build("dependencies", "--configuration", "compileClasspath").getOutput()).contains("1.7.20");
.build("dependencies", "--configuration", "compileClasspath")
.getOutput()).contains("1.7.20");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -63,7 +63,7 @@ class PackagingDocumentationTests {
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
.isEqualTo("com.example.ExampleApplication");
}
}
@@ -75,7 +75,7 @@ class PackagingDocumentationTests {
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
.isEqualTo("com.example.ExampleApplication");
}
}
@@ -87,7 +87,7 @@ class PackagingDocumentationTests {
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
.isEqualTo("com.example.ExampleApplication");
}
}
@@ -99,7 +99,7 @@ class PackagingDocumentationTests {
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.ExampleApplication");
.isEqualTo("com.example.ExampleApplication");
}
}
@@ -166,7 +166,7 @@ class PackagingDocumentationTests {
assertThat(file).isFile();
try (JarFile jar = new JarFile(file)) {
assertThat(jar.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo("org.springframework.boot.loader.PropertiesLauncher");
.isEqualTo("org.springframework.boot.loader.PropertiesLauncher");
}
}
@@ -222,8 +222,10 @@ class PackagingDocumentationTests {
try (JarFile jar = new JarFile(file)) {
JarEntry entry = jar.getJarEntry("BOOT-INF/layers.idx");
assertThat(entry).isNotNull();
assertThat(Collections.list(jar.entries()).stream().map(JarEntry::getName)
.filter((name) -> name.startsWith("BOOT-INF/lib/spring-boot"))).isNotEmpty();
assertThat(Collections.list(jar.entries())
.stream()
.map(JarEntry::getName)
.filter((name) -> name.startsWith("BOOT-INF/lib/spring-boot"))).isNotEmpty();
}
}
@@ -236,100 +238,105 @@ class PackagingDocumentationTests {
try (JarFile jar = new JarFile(file)) {
JarEntry entry = jar.getJarEntry("BOOT-INF/layers.idx");
assertThat(entry).isNotNull();
assertThat(Collections.list(jar.entries()).stream().map(JarEntry::getName)
.filter((name) -> name.startsWith("BOOT-INF/lib/spring-boot"))).isEmpty();
assertThat(Collections.list(jar.entries())
.stream()
.map(JarEntry::getName)
.filter((name) -> name.startsWith("BOOT-INF/lib/spring-boot"))).isEmpty();
}
}
@TestTemplate
void bootBuildImageWithBuilder() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-builder")
.build("bootBuildImageBuilder");
.build("bootBuildImageBuilder");
assertThat(result.getOutput()).contains("builder=mine/java-cnb-builder").contains("runImage=mine/java-cnb-run");
}
@TestTemplate
void bootBuildImageWithCustomBuildpackJvmVersion() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-env")
.build("bootBuildImageEnvironment");
.build("bootBuildImageEnvironment");
assertThat(result.getOutput()).contains("BP_JVM_VERSION=17");
}
@TestTemplate
void bootBuildImageWithCustomProxySettings() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-env-proxy")
.build("bootBuildImageEnvironment");
.build("bootBuildImageEnvironment");
assertThat(result.getOutput()).contains("HTTP_PROXY=http://proxy.example.com")
.contains("HTTPS_PROXY=https://proxy.example.com");
.contains("HTTPS_PROXY=https://proxy.example.com");
}
@TestTemplate
void bootBuildImageWithCustomRuntimeConfiguration() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-env-runtime")
.build("bootBuildImageEnvironment");
.build("bootBuildImageEnvironment");
assertThat(result.getOutput()).contains("BPE_DELIM_JAVA_TOOL_OPTIONS= ")
.contains("BPE_APPEND_JAVA_TOOL_OPTIONS=-XX:+HeapDumpOnOutOfMemoryError");
.contains("BPE_APPEND_JAVA_TOOL_OPTIONS=-XX:+HeapDumpOnOutOfMemoryError");
}
@TestTemplate
void bootBuildImageWithCustomImageName() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-name")
.build("bootBuildImageName");
.build("bootBuildImageName");
assertThat(result.getOutput()).contains("example.com/library/" + this.gradleBuild.getProjectDir().getName());
}
@TestTemplate
void bootBuildImageWithDockerHostMinikube() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-host")
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("host=tcp://192.168.99.100:2376").contains("tlsVerify=true")
.contains("certPath=/home/user/.minikube/certs");
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("host=tcp://192.168.99.100:2376")
.contains("tlsVerify=true")
.contains("certPath=/home/user/.minikube/certs");
}
@TestTemplate
void bootBuildImageWithDockerHostPodman() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-host-podman")
.build("bootBuildImageDocker");
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("host=unix:///run/user/1000/podman/podman.sock")
.contains("bindHostToBuilder=true");
.contains("bindHostToBuilder=true");
}
@TestTemplate
void bootBuildImageWithDockerUserAuth() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-auth-user")
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("username=user").contains("password=secret")
.contains("url=https://docker.example.com/v1/").contains("email=user@example.com");
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("username=user")
.contains("password=secret")
.contains("url=https://docker.example.com/v1/")
.contains("email=user@example.com");
}
@TestTemplate
void bootBuildImageWithDockerTokenAuth() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-docker-auth-token")
.build("bootBuildImageDocker");
.build("bootBuildImageDocker");
assertThat(result.getOutput()).contains("token=9cbaf023786cd7...");
}
@TestTemplate
void bootBuildImagePublish() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-publish")
.build("bootBuildImagePublish");
.build("bootBuildImagePublish");
assertThat(result.getOutput()).contains("true");
}
@TestTemplate
void bootBuildImageWithBuildpacks() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-buildpacks")
.build("bootBuildImageBuildpacks");
.build("bootBuildImageBuildpacks");
assertThat(result.getOutput()).contains("file:///path/to/example-buildpack.tgz")
.contains("urn:cnb:builder:paketo-buildpacks/java");
.contains("urn:cnb:builder:paketo-buildpacks/java");
}
@TestTemplate
void bootBuildImageWithCaches() {
BuildResult result = this.gradleBuild.script("src/docs/gradle/packaging/boot-build-image-caches")
.build("bootBuildImageCaches");
.build("bootBuildImageCaches");
assertThat(result.getOutput()).containsPattern("buildCache=cache-gradle-[\\d]+.build")
.containsPattern("launchCache=cache-gradle-[\\d]+.launch");
.containsPattern("launchCache=cache-gradle-[\\d]+.launch");
}
protected void jarFile(File file) throws IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,8 +37,9 @@ class PublishingDocumentationTests {
@TestTemplate
void mavenPublish() {
assertThat(this.gradleBuild.script("src/docs/gradle/publishing/maven-publish").build("publishingConfiguration")
.getOutput()).contains("MavenPublication").contains("https://repo.example.com");
assertThat(this.gradleBuild.script("src/docs/gradle/publishing/maven-publish")
.build("publishingConfiguration")
.getOutput()).contains("MavenPublication").contains("https://repo.example.com");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,46 +44,51 @@ class RunningDocumentationTests {
void bootRunMain() throws IOException {
writeMainClass();
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-main").build("bootRun").getOutput())
.contains("com.example.ExampleApplication");
.contains("com.example.ExampleApplication");
}
@TestTemplate
void applicationPluginMainClassName() throws IOException {
writeMainClass();
assertThat(this.gradleBuild.script("src/docs/gradle/running/application-plugin-main-class-name")
.build("bootRun").getOutput()).contains("com.example.ExampleApplication");
.build("bootRun")
.getOutput()).contains("com.example.ExampleApplication");
}
@TestTemplate
void springBootDslMainClassName() throws IOException {
writeMainClass();
assertThat(this.gradleBuild.script("src/docs/gradle/running/spring-boot-dsl-main-class-name").build("bootRun")
.getOutput()).contains("com.example.ExampleApplication");
assertThat(this.gradleBuild.script("src/docs/gradle/running/spring-boot-dsl-main-class-name")
.build("bootRun")
.getOutput()).contains("com.example.ExampleApplication");
}
@TestTemplate
void bootRunSourceResources() {
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-source-resources")
.build("configuredClasspath").getOutput()).contains(new File("src/main/resources").getPath());
.build("configuredClasspath")
.getOutput()).contains(new File("src/main/resources").getPath());
}
@TestTemplate
void bootRunDisableOptimizedLaunch() {
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-disable-optimized-launch")
.build("optimizedLaunch").getOutput()).contains("false");
.build("optimizedLaunch")
.getOutput()).contains("false");
}
@TestTemplate
void bootRunSystemPropertyDefaultValue() {
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-system-property")
.build("configuredSystemProperties").getOutput()).contains("com.example.property = default");
.build("configuredSystemProperties")
.getOutput()).contains("com.example.property = default");
}
@TestTemplate
void bootRunSystemProperty() {
assertThat(this.gradleBuild.script("src/docs/gradle/running/boot-run-system-property")
.build("-Pexample=custom", "configuredSystemProperties").getOutput())
.contains("com.example.property = custom");
.build("-Pexample=custom", "configuredSystemProperties")
.getOutput()).contains("com.example.property = custom");
}
private void writeMainClass() throws IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,7 +44,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void basicJar() {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", this.gradleBuild.getProjectDir().getName());
@@ -55,7 +55,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void jarWithCustomName() {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", "foo");
@@ -66,7 +66,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void basicWar() {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", this.gradleBuild.getProjectDir().getName());
@@ -77,7 +77,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void warWithCustomName() {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", "foo");
@@ -88,7 +88,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void additionalProperties() {
assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Properties properties = buildInfoProperties();
assertThat(properties).containsEntry("build.name", this.gradleBuild.getProjectDir().getName());
assertThat(properties).containsEntry("build.artifact", this.gradleBuild.getProjectDir().getName());
@@ -101,7 +101,7 @@ class BuildInfoDslIntegrationTests {
@TestTemplate
void classesDependency() {
assertThat(this.gradleBuild.build("classes", "--stacktrace").task(":bootBuildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
private Properties buildInfoProperties() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -49,11 +49,12 @@ final class GradleCompatibilityExtension implements TestTemplateInvocationContex
public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
Stream<String> gradleVersions = GRADLE_VERSIONS.stream();
GradleCompatibility gradleCompatibility = AnnotationUtils
.findAnnotation(context.getRequiredTestClass(), GradleCompatibility.class).get();
.findAnnotation(context.getRequiredTestClass(), GradleCompatibility.class)
.get();
if (StringUtils.hasText(gradleCompatibility.versionsLessThan())) {
GradleVersion upperExclusive = GradleVersion.version(gradleCompatibility.versionsLessThan());
gradleVersions = gradleVersions
.filter((version) -> GradleVersion.version(version).compareTo(upperExclusive) < 0);
.filter((version) -> GradleVersion.version(version).compareTo(upperExclusive) < 0);
}
return gradleVersions.flatMap((version) -> {
List<TestTemplateInvocationContext> invocationContexts = new ArrayList<>();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -55,37 +55,37 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void noBootDistributionWithoutApplicationPluginApplied() {
assertThat(this.gradleBuild.build("distributionExists", "-PdistributionName=boot").getOutput())
.contains("boot exists = false");
.contains("boot exists = false");
}
@TestTemplate
void applyingApplicationPluginCreatesBootDistribution() {
assertThat(this.gradleBuild.build("distributionExists", "-PdistributionName=boot", "-PapplyApplicationPlugin")
.getOutput()).contains("boot exists = true");
.getOutput()).contains("boot exists = true");
}
@TestTemplate
void noBootStartScriptsTaskWithoutApplicationPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootStartScripts").getOutput())
.contains("bootStartScripts exists = false");
.contains("bootStartScripts exists = false");
}
@TestTemplate
void applyingApplicationPluginCreatesBootStartScriptsTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootStartScripts", "-PapplyApplicationPlugin")
.getOutput()).contains("bootStartScripts exists = true");
.getOutput()).contains("bootStartScripts exists = true");
}
@TestTemplate
void createsBootStartScriptsTaskUsesApplicationPluginsDefaultJvmOpts() {
assertThat(this.gradleBuild.build("startScriptsDefaultJvmOpts", "-PapplyApplicationPlugin").getOutput())
.contains("bootStartScripts defaultJvmOpts = [-Dcom.example.a=alpha, -Dcom.example.b=bravo]");
.contains("bootStartScripts defaultJvmOpts = [-Dcom.example.a=alpha, -Dcom.example.b=bravo]");
}
@TestTemplate
void zipDistributionForJarCanBeBuilt() throws IOException {
assertThat(this.gradleBuild.build("bootDistZip").task(":bootDistZip").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/" + name + "-boot.zip");
assertThat(distribution).isFile();
@@ -97,7 +97,7 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void tarDistributionForJarCanBeBuilt() throws IOException {
assertThat(this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/" + name + "-boot.tar");
assertThat(distribution).isFile();
@@ -109,7 +109,7 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void zipDistributionForWarCanBeBuilt() throws IOException {
assertThat(this.gradleBuild.build("bootDistZip").task(":bootDistZip").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/" + name + "-boot.zip");
assertThat(distribution).isFile();
@@ -121,7 +121,7 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void tarDistributionForWarCanBeBuilt() throws IOException {
assertThat(this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/" + name + "-boot.tar");
assertThat(distribution).isFile();
@@ -133,7 +133,7 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void applicationNameCanBeUsedToCustomizeDistributionName() throws IOException {
assertThat(this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/custom-boot.tar");
assertThat(distribution).isFile();
String name = this.gradleBuild.getProjectDir().getName();
@@ -145,7 +145,7 @@ class ApplicationPluginActionIntegrationTests {
@TestTemplate
void scriptsHaveCorrectPermissions() throws IOException {
assertThat(this.gradleBuild.build("bootDistTar").task(":bootDistTar").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String name = this.gradleBuild.getProjectDir().getName();
File distribution = new File(this.gradleBuild.getProjectDir(), "build/distributions/" + name + "-boot.tar");
assertThat(distribution).isFile();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,14 +37,16 @@ class DependencyManagementPluginActionIntegrationTests {
@TestTemplate
void noDependencyManagementIsAppliedByDefault() {
assertThat(this.gradleBuild.build("doesNotHaveDependencyManagement").task(":doesNotHaveDependencyManagement")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("doesNotHaveDependencyManagement")
.task(":doesNotHaveDependencyManagement")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void bomIsImportedWhenDependencyManagementPluginIsApplied() {
assertThat(this.gradleBuild.build("hasDependencyManagement", "-PapplyDependencyManagementPlugin")
.task(":hasDependencyManagement").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
.task(":hasDependencyManagement")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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,52 +48,53 @@ class JavaPluginActionIntegrationTests {
@TestTemplate
void noBootJarTaskWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootJar").getOutput())
.contains("bootJar exists = false");
.contains("bootJar exists = false");
}
@TestTemplate
void applyingJavaPluginCreatesBootJarTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootJar", "-PapplyJavaPlugin").getOutput())
.contains("bootJar exists = true");
.contains("bootJar exists = true");
}
@TestTemplate
void noBootRunTaskWithoutJavaPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootRun").getOutput())
.contains("bootRun exists = false");
.contains("bootRun exists = false");
}
@TestTemplate
void applyingJavaPluginCreatesBootRunTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootRun", "-PapplyJavaPlugin").getOutput())
.contains("bootRun exists = true");
.contains("bootRun exists = true");
}
@TestTemplate
void javaCompileTasksUseUtf8Encoding() {
assertThat(this.gradleBuild.build("javaCompileEncoding", "-PapplyJavaPlugin").getOutput())
.contains("compileJava = UTF-8").contains("compileTestJava = UTF-8");
.contains("compileJava = UTF-8")
.contains("compileTestJava = UTF-8");
}
@TestTemplate
void javaCompileTasksUseParametersCompilerFlagByDefault() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-parameters]")
.contains("compileTestJava compiler args: [-parameters]");
.contains("compileJava compiler args: [-parameters]")
.contains("compileTestJava compiler args: [-parameters]");
}
@TestTemplate
void javaCompileTasksUseParametersAndAdditionalCompilerFlags() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-parameters, -Xlint:all]")
.contains("compileTestJava compiler args: [-parameters, -Xlint:all]");
.contains("compileJava compiler args: [-parameters, -Xlint:all]")
.contains("compileTestJava compiler args: [-parameters, -Xlint:all]");
}
@TestTemplate
void javaCompileTasksCanOverrideDefaultParametersCompilerFlag() {
assertThat(this.gradleBuild.build("javaCompileTasksCompilerArgs").getOutput())
.contains("compileJava compiler args: [-Xlint:all]")
.contains("compileTestJava compiler args: [-Xlint:all]");
.contains("compileJava compiler args: [-Xlint:all]")
.contains("compileTestJava compiler args: [-Xlint:all]");
}
@TestTemplate
@@ -120,7 +121,7 @@ class JavaPluginActionIntegrationTests {
File libs = new File(this.gradleBuild.getProjectDir(), "libs");
libs.mkdirs();
new JarOutputStream(new FileOutputStream(new File(libs, "spring-boot-configuration-processor-1.2.3.jar")))
.close();
.close();
BuildResult result = this.gradleBuild.build("compileJava");
assertThat(result.task(":compileJava").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("compileJava compiler args: [-parameters, -Aorg.springframework.boot."
@@ -139,27 +140,32 @@ class JavaPluginActionIntegrationTests {
@TestTemplate
void applyingJavaPluginCreatesDevelopmentOnlyConfiguration() {
assertThat(this.gradleBuild
.build("configurationExists", "-PconfigurationName=developmentOnly", "-PapplyJavaPlugin").getOutput())
.contains("developmentOnly exists = true");
.build("configurationExists", "-PconfigurationName=developmentOnly", "-PapplyJavaPlugin")
.getOutput()).contains("developmentOnly exists = true");
}
@TestTemplate
void productionRuntimeClasspathIsConfiguredWithAttributes() {
assertThat(this.gradleBuild
.build("configurationAttributes", "-PconfigurationName=productionRuntimeClasspath", "-PapplyJavaPlugin")
.getOutput()).contains("3 productionRuntimeClasspath attributes:")
.contains("org.gradle.usage: java-runtime").contains("org.gradle.libraryelements: jar")
.contains("org.gradle.dependency.bundling: external");
.build("configurationAttributes", "-PconfigurationName=productionRuntimeClasspath", "-PapplyJavaPlugin")
.getOutput()).contains("3 productionRuntimeClasspath attributes:")
.contains("org.gradle.usage: java-runtime")
.contains("org.gradle.libraryelements: jar")
.contains("org.gradle.dependency.bundling: external");
}
@TestTemplate
void productionRuntimeClasspathIsConfiguredWithResolvabilityAndConsumabilityThatMatchesRuntimeClasspath() {
String runtime = this.gradleBuild.build("configurationResolvabilityAndConsumability",
"-PconfigurationName=runtimeClasspath", "-PapplyJavaPlugin").getOutput();
String runtime = this.gradleBuild
.build("configurationResolvabilityAndConsumability", "-PconfigurationName=runtimeClasspath",
"-PapplyJavaPlugin")
.getOutput();
assertThat(runtime).contains("canBeResolved: true");
assertThat(runtime).contains("canBeConsumed: false");
String productionRuntime = this.gradleBuild.build("configurationResolvabilityAndConsumability",
"-PconfigurationName=productionRuntimeClasspath", "-PapplyJavaPlugin").getOutput();
String productionRuntime = this.gradleBuild
.build("configurationResolvabilityAndConsumability", "-PconfigurationName=productionRuntimeClasspath",
"-PapplyJavaPlugin")
.getOutput();
assertThat(productionRuntime).contains("canBeResolved: true");
assertThat(productionRuntime).contains("canBeConsumed: false");
}
@@ -177,7 +183,7 @@ class JavaPluginActionIntegrationTests {
}
}
if (!this.gradleBuild.isConfigurationCache() && GradleVersion.version(this.gradleBuild.getGradleVersion())
.compareTo(GradleVersion.version("7.3.3")) < 0) {
.compareTo(GradleVersion.version("7.3.3")) < 0) {
assertThat(configured).containsExactly("help");
}
else {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -49,20 +49,22 @@ class KotlinPluginActionIntegrationTests {
@TestTemplate
void kotlinVersionPropertyIsSet() {
String output = this.gradleBuild.build("kotlinVersion", "dependencies", "--configuration", "compileClasspath")
.getOutput();
.getOutput();
assertThat(output).containsPattern("Kotlin version: [0-9]\\.[0-9]\\.[0-9]+");
}
@TestTemplate
void kotlinCompileTasksUseJavaParametersFlagByDefault() {
assertThat(this.gradleBuild.build("kotlinCompileTasksJavaParameters").getOutput())
.contains("compileKotlin java parameters: true").contains("compileTestKotlin java parameters: true");
.contains("compileKotlin java parameters: true")
.contains("compileTestKotlin java parameters: true");
}
@TestTemplate
void kotlinCompileTasksCanOverrideDefaultJavaParametersFlag() {
assertThat(this.gradleBuild.build("kotlinCompileTasksJavaParameters").getOutput())
.contains("compileKotlin java parameters: false").contains("compileTestKotlin java parameters: false");
.contains("compileKotlin java parameters: false")
.contains("compileTestKotlin java parameters: false");
}
@TestTemplate

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -50,7 +50,7 @@ class NativeImagePluginActionIntegrationTests {
@TestTemplate
void applyingNativeImagePluginAppliesAotPlugin() {
assertThat(this.gradleBuild.build("aotPluginApplied").getOutput())
.contains("org.springframework.boot.aot applied = true");
.contains("org.springframework.boot.aot applied = true");
}
@TestTemplate

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -37,7 +37,7 @@ class OnlyDependencyManagementIntegrationTests {
@TestTemplate
void dependencyManagementCanBeConfiguredUsingCoordinatesConstant() {
assertThat(this.gradleBuild.build("dependencyManagement").getOutput())
.contains("org.springframework.boot:spring-boot-starter ");
.contains("org.springframework.boot:spring-boot-starter ");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -42,25 +42,25 @@ class SpringBootAotPluginIntegrationTests {
@TestTemplate
void noProcessAotTaskWithoutAotPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=processAot").getOutput())
.contains("processAot exists = false");
.contains("processAot exists = false");
}
@TestTemplate
void noProcessTestAotTaskWithoutAotPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=processTestAot").getOutput())
.contains("processTestAot exists = false");
.contains("processTestAot exists = false");
}
@TestTemplate
void applyingAotPluginCreatesProcessAotTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=processAot").getOutput())
.contains("processAot exists = true");
.contains("processAot exists = true");
}
@TestTemplate
void applyingAotPluginCreatesProcessTestAotTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=processTestAot").getOutput())
.contains("processTestAot exists = true");
.contains("processTestAot exists = true");
}
@TestTemplate
@@ -100,13 +100,13 @@ class SpringBootAotPluginIntegrationTests {
writeMainClass("org.springframework.boot", "SpringApplicationAotProcessor");
writeMainClass("com.example", "Main");
assertThat(this.gradleBuild.build("processAot").task(":processAot").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void processTestAotIsSkippedWhenProjectHasNoTestSource() {
assertThat(this.gradleBuild.build("processTestAot").task(":processTestAot").getOutcome())
.isEqualTo(TaskOutcome.NO_SOURCE);
.isEqualTo(TaskOutcome.NO_SOURCE);
}
private void writeMainClass(String packageName, String className) throws IOException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -39,7 +39,7 @@ class SpringBootPluginIntegrationTests {
void failFastWithVersionOfGradle7LowerThanRequired() {
BuildResult result = this.gradleBuild.gradleVersion("7.3.3").buildAndFail();
assertThat(result.getOutput())
.contains("Spring Boot plugin requires Gradle 7.x (7.4 or later). The current version is Gradle 7.3.3");
.contains("Spring Boot plugin requires Gradle 7.x (7.4 or later). The current version is Gradle 7.3.3");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -45,7 +45,7 @@ class SpringBootPluginTests {
Project project = GradleProjectBuilder.builder().withProjectDir(this.temp).build();
project.getPlugins().apply(SpringBootPlugin.class);
Configuration bootArchives = project.getConfigurations()
.getByName(SpringBootPlugin.BOOT_ARCHIVES_CONFIGURATION_NAME);
.getByName(SpringBootPlugin.BOOT_ARCHIVES_CONFIGURATION_NAME);
assertThat(bootArchives.isCanBeResolved()).isFalse();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -46,13 +46,13 @@ class WarPluginActionIntegrationTests {
@TestTemplate
void noBootWarTaskWithoutWarPluginApplied() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootWar").getOutput())
.contains("bootWar exists = false");
.contains("bootWar exists = false");
}
@TestTemplate
void applyingWarPluginCreatesBootWarTask() {
assertThat(this.gradleBuild.build("taskExists", "-PtaskName=bootWar", "-PapplyWarPlugin").getOutput())
.contains("bootWar exists = true");
.contains("bootWar exists = true");
}
@TestTemplate

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -84,17 +84,21 @@ class BuildInfoIntegrationTests {
@TestTemplate
void upToDateWhenExecutedTwiceWithFixedTime() {
assertThat(this.gradleBuild.build("buildInfo", "-PnullTime").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("buildInfo", "-PnullTime").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
.isEqualTo(TaskOutcome.UP_TO_DATE);
}
@TestTemplate
void notUpToDateWhenExecutedTwiceWithFixedTimeAndChangedProjectVersion() {
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.1.0").build("buildInfo").task(":buildInfo")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.2.0").build("buildInfo").task(":buildInfo")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.1.0")
.build("buildInfo")
.task(":buildInfo")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("projectVersion", "0.2.0")
.build("buildInfo")
.task(":buildInfo")
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
@@ -111,13 +115,13 @@ class BuildInfoIntegrationTests {
@TestTemplate
void reproducibleOutputWithFixedTime() throws IOException, InterruptedException {
assertThat(this.gradleBuild.build("buildInfo", "-PnullTime").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
File buildInfoProperties = new File(this.gradleBuild.getProjectDir(), "build/buildInfo/build-info.properties");
String firstHash = FileUtils.sha1Hash(buildInfoProperties);
assertThat(buildInfoProperties.delete()).isTrue();
Thread.sleep(1500);
assertThat(this.gradleBuild.build("buildInfo", "-PnullTime").task(":buildInfo").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String secondHash = FileUtils.sha1Hash(buildInfoProperties);
assertThat(firstHash).isEqualTo(secondHash);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -168,14 +168,15 @@ class BuildInfoTests {
void nullAdditionalPropertyProducesInformativeFailure() {
BuildInfo task = createTask(createProject("test"));
assertThatThrownBy(() -> task.getProperties().getAdditional().put("a", null))
.hasMessage("Cannot add an entry with a null value to a property of type Map.");
.hasMessage("Cannot add an entry with a null value to a property of type Map.");
}
private Project createProject(String projectName) {
File projectDir = new File(this.temp, projectName);
Project project = GradleProjectBuilder.builder().withProjectDir(projectDir).withName(projectName).build();
((ProjectInternal) project).getServices().get(GradlePropertiesController.class)
.loadGradlePropertiesFrom(projectDir);
((ProjectInternal) project).getServices()
.get(GradlePropertiesController.class)
.loadGradlePropertiesFrom(projectDir);
return project;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -85,18 +85,18 @@ abstract class AbstractBootArchiveIntegrationTests {
@TestTemplate
void basicBuild() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void reproducibleArchive() throws IOException, InterruptedException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
File jar = new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0];
String firstHash = FileUtils.sha1Hash(jar);
Thread.sleep(1500);
assertThat(this.gradleBuild.build("clean", this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
String secondHash = FileUtils.sha1Hash(jar);
assertThat(firstHash).isEqualTo(secondHash);
}
@@ -104,67 +104,81 @@ abstract class AbstractBootArchiveIntegrationTests {
@TestTemplate
void upToDateWhenBuiltTwice() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
.isEqualTo(TaskOutcome.UP_TO_DATE);
}
@TestTemplate
void upToDateWhenBuiltTwiceWithLaunchScriptIncluded() {
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.build("-PincludeLaunchScript=true", this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
}
@TestTemplate
void notUpToDateWhenLaunchScriptWasNotIncludedAndThenIsIncluded() {
assertThat(this.gradleBuild.scriptProperty("launchScript", "").build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void notUpToDateWhenLaunchScriptWasIncludedAndThenIsNotIncluded() {
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "").build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "launchScript()")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScript", "")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void notUpToDateWhenLaunchScriptPropertyChanges() {
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "alpha").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "bravo").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "alpha")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("launchScriptProperty", "bravo")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void applicationPluginMainClassNameIsUsed() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
.isEqualTo("com.example.CustomMain");
}
}
@TestTemplate
void springBootExtensionMainClassNameIsUsed() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
.isEqualTo("com.example.CustomMain");
}
}
@TestTemplate
void duplicatesAreHandledGracefully() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
@@ -173,13 +187,17 @@ abstract class AbstractBootArchiveIntegrationTests {
srcMainResources.mkdirs();
new File(srcMainResources, "resource").createNewFile();
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
Stream<String> libEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName).filter((name) -> name.startsWith(this.libPath));
Stream<String> libEntryNames = jarFile.stream()
.filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName)
.filter((name) -> name.startsWith(this.libPath));
assertThat(libEntryNames).containsExactly(this.libPath + "commons-io-2.6.jar");
Stream<String> classesEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName).filter((name) -> name.startsWith(this.classesPath));
Stream<String> classesEntryNames = jarFile.stream()
.filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName)
.filter((name) -> name.startsWith(this.classesPath));
assertThat(classesEntryNames).containsExactly(this.classesPath + "resource");
}
}
@@ -187,10 +205,12 @@ abstract class AbstractBootArchiveIntegrationTests {
@TestTemplate
void developmentOnlyDependenciesCanBeIncludedInTheArchive() throws IOException {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
Stream<String> libEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName).filter((name) -> name.startsWith(this.libPath));
Stream<String> libEntryNames = jarFile.stream()
.filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName)
.filter((name) -> name.startsWith(this.libPath));
assertThat(libEntryNames).containsExactly(this.libPath + "commons-io-2.6.jar",
this.libPath + "commons-lang3-3.9.jar");
}
@@ -202,10 +222,12 @@ abstract class AbstractBootArchiveIntegrationTests {
createDependenciesStarterJar(new File(flatDirRepository, "starter.jar"));
createStandardJar(new File(flatDirRepository, "standard.jar"));
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
Stream<String> libEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName).filter((name) -> name.startsWith(this.libPath));
Stream<String> libEntryNames = jarFile.stream()
.filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName)
.filter((name) -> name.startsWith(this.libPath));
assertThat(libEntryNames).containsExactly(this.libPath + "standard.jar");
}
}
@@ -214,44 +236,56 @@ abstract class AbstractBootArchiveIntegrationTests {
void startClassIsSetByResolvingTheMainClass() throws IOException {
copyMainClassApplication();
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
Attributes mainAttributes = jarFile.getManifest().getMainAttributes();
assertThat(mainAttributes.getValue("Start-Class"))
.isEqualTo("com.example." + this.taskName.toLowerCase(Locale.ENGLISH) + ".main.CustomMainClass");
.isEqualTo("com.example." + this.taskName.toLowerCase(Locale.ENGLISH) + ".main.CustomMainClass");
}
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.UP_TO_DATE);
.isEqualTo(TaskOutcome.UP_TO_DATE);
}
@TestTemplate
void upToDateWhenBuiltWithDefaultLayeredAndThenWithExplicitLayered() {
assertThat(this.gradleBuild.scriptProperty("layered", "").build("" + this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layered", "layered {}").build("" + this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
assertThat(this.gradleBuild.scriptProperty("layered", "")
.build("" + this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layered", "layered {}")
.build("" + this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.UP_TO_DATE);
}
@TestTemplate
void notUpToDateWhenBuiltWithoutLayersAndThenWithLayers() {
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = false").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = true").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = false")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerEnablement", "enabled = true")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void notUpToDateWhenBuiltWithLayerToolsAndThenWithoutLayerTools() {
assertThat(this.gradleBuild.scriptProperty("layerTools", "").build(this.taskName).task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerTools", "includeLayerTools = false").build(this.taskName)
.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerTools", "")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(this.gradleBuild.scriptProperty("layerTools", "includeLayerTools = false")
.build(this.taskName)
.task(":" + this.taskName)
.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
void layersWithCustomSourceSet() {
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate
@@ -259,7 +293,7 @@ abstract class AbstractBootArchiveIntegrationTests {
writeMainClass();
writeResource();
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Map<String, List<String>> indexedLayers;
String layerToolsJar = this.libPath + JarModeLibrary.LAYER_TOOLS.getName();
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
@@ -293,7 +327,7 @@ abstract class AbstractBootArchiveIntegrationTests {
assertThat(indexedLayers.get("spring-boot-loader")).containsExactly("org/");
assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies);
assertThat(indexedLayers.get("application"))
.containsExactly(getExpectedApplicationLayerContents(this.classesPath));
.containsExactly(getExpectedApplicationLayerContents(this.classesPath));
BuildResult listLayers = this.gradleBuild.build("listLayers");
assertThat(listLayers.task(":listLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
String listLayersOutput = listLayers.getOutput();
@@ -311,7 +345,7 @@ abstract class AbstractBootArchiveIntegrationTests {
writeMainClass();
writeResource();
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
Map<String, List<String>> indexedLayers;
String layerToolsJar = this.libPath + JarModeLibrary.LAYER_TOOLS.getName();
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
@@ -341,8 +375,8 @@ abstract class AbstractBootArchiveIntegrationTests {
assertThat(indexedLayers.get("spring-boot-loader")).containsExactly("org/");
assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies);
assertThat(indexedLayers.get("application"))
.containsExactly(getExpectedApplicationLayerContents(this.classesPath, this.libPath + "alpha-1.2.3.jar",
this.libPath + "bravo-1.2.3.jar", this.libPath + "charlie-1.2.3.jar"));
.containsExactly(getExpectedApplicationLayerContents(this.classesPath, this.libPath + "alpha-1.2.3.jar",
this.libPath + "bravo-1.2.3.jar", this.libPath + "charlie-1.2.3.jar"));
BuildResult listLayers = this.gradleBuild.build("listLayers");
assertThat(listLayers.task(":listLayers").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
String listLayersOutput = listLayers.getOutput();
@@ -435,7 +469,7 @@ abstract class AbstractBootArchiveIntegrationTests {
expectedSnapshotDependencies.add(this.libPath + "library-1.0-SNAPSHOT.jar");
(layerToolsJar.contains("SNAPSHOT") ? expectedSnapshotDependencies : expectedDependencies).add(layerToolsJar);
assertThat(indexedLayers.get("subproject-dependencies"))
.containsExactlyElementsOf(expectedSubprojectDependencies);
.containsExactlyElementsOf(expectedSubprojectDependencies);
assertThat(indexedLayers.get("dependencies")).containsExactlyElementsOf(expectedDependencies);
assertThat(indexedLayers.get("commons-dependencies")).containsExactly(this.libPath + "commons-lang3-3.9.jar");
assertThat(indexedLayers.get("snapshot-dependencies")).containsExactlyElementsOf(expectedSnapshotDependencies);
@@ -471,8 +505,10 @@ abstract class AbstractBootArchiveIntegrationTests {
BuildResult build = this.gradleBuild.build(this.taskName);
assertThat(build.task(":" + this.taskName).getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
Stream<String> classesEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName).filter((name) -> name.startsWith(this.classesPath));
Stream<String> classesEntryNames = jarFile.stream()
.filter((entry) -> !entry.isDirectory())
.map(JarEntry::getName)
.filter((name) -> name.startsWith(this.classesPath));
assertThat(classesEntryNames).containsExactly(this.classesPath + "example/Main.class",
this.classesPath + "example/Secondary.class");
}
@@ -551,8 +587,9 @@ abstract class AbstractBootArchiveIntegrationTests {
private void writeResource() {
try {
Path path = this.gradleBuild.getProjectDir().toPath()
.resolve(Paths.get("src", "main", "resources", "static", "file.txt"));
Path path = this.gradleBuild.getProjectDir()
.toPath()
.resolve(Paths.get("src", "main", "resources", "static", "file.txt"));
Files.createDirectories(path.getParent());
Files.createFile(path);
}
@@ -587,8 +624,11 @@ abstract class AbstractBootArchiveIntegrationTests {
assertThat(layer).isDirectory();
List<String> files;
try (Stream<Path> pathStream = Files.walk(layer.toPath())) {
files = pathStream.filter((path) -> path.toFile().isFile()).map(layer.toPath()::relativize)
.map(Path::toString).map(StringUtils::cleanPath).toList();
files = pathStream.filter((path) -> path.toFile().isFile())
.map(layer.toPath()::relativize)
.map(Path::toString)
.map(StringUtils::cleanPath)
.toList();
}
extractedLayers.put(layerName, files);
}

View File

@@ -129,11 +129,11 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class")).isEqualTo(this.launcherClass);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class")).isEqualTo("com.example.Main");
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classes"))
.isEqualTo(this.classesPath);
.isEqualTo(this.classesPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(this.libPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Version")).isNotNull();
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Title"))
.isEqualTo(this.project.getName());
.isEqualTo(this.project.getName());
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version")).isNull();
}
}
@@ -145,7 +145,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Title"))
.isEqualTo("Customized");
.isEqualTo("Customized");
}
}
@@ -167,7 +167,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Implementation-Version"))
.isEqualTo("Customized");
.isEqualTo("Customized");
}
}
@@ -177,10 +177,12 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
this.task.classpath(jarFile("one.jar"), jarFile("two.jar"));
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getEntry(this.libPath + "one.jar")).isNotNull().extracting(ZipEntry::getMethod)
.isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry(this.libPath + "two.jar")).isNotNull().extracting(ZipEntry::getMethod)
.isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry(this.libPath + "one.jar")).isNotNull()
.extracting(ZipEntry::getMethod)
.isEqualTo(ZipEntry.STORED);
assertThat(jarFile.getEntry(this.libPath + "two.jar")).isNotNull()
.extracting(ZipEntry::getMethod)
.isEqualTo(ZipEntry.STORED);
}
}
@@ -314,7 +316,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
properties.put("initInfoDescription", this.project.getDescription());
File archiveFile = this.task.getArchiveFile().get().getAsFile();
assertThat(Files.readAllBytes(archiveFile.toPath()))
.startsWith(new DefaultLaunchScript(null, properties).toByteArray());
.startsWith(new DefaultLaunchScript(null, properties).toByteArray());
try (ZipFile zipFile = new ZipFile(archiveFile)) {
assertThat(zipFile.getEntries().hasMoreElements()).isTrue();
}
@@ -362,7 +364,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
assertThat(this.task.getArchiveFile().get().getAsFile()).exists();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class"))
.isEqualTo("com.example.CustomLauncher");
.isEqualTo("com.example.CustomLauncher");
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class")).isEqualTo("com.example.Main");
assertThat(jarFile.getEntry("org/springframework/boot/loader/LaunchedURLClassLoader.class")).isNull();
}
@@ -377,7 +379,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Main-Class")).isEqualTo(this.launcherClass);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Start-Class"))
.isEqualTo("com.example.CustomMain");
.isEqualTo("com.example.CustomMain");
}
}
@@ -399,7 +401,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
@Test
void constantTimestampMatchesGradleInternalTimestamp() {
assertThat(BootZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES)
.isEqualTo(ZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES);
.isEqualTo(ZipCopyAction.CONSTANT_TIME_FOR_ZIP_ENTRIES);
}
@Test
@@ -477,10 +479,10 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
executeTask();
try (JarFile jarFile = new JarFile(this.task.getArchiveFile().get().getAsFile())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classes"))
.isEqualTo(this.classesPath);
.isEqualTo(this.classesPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(this.libPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index"))
.isEqualTo(this.indexPath + "layers.idx");
.isEqualTo(this.indexPath + "layers.idx");
assertThat(getEntryNames(jarFile)).contains(this.libPath + JarModeLibrary.LAYER_TOOLS.getName());
}
}
@@ -496,10 +498,10 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
void whenJarIsLayeredThenManifestContainsEntryForLayersIndexInPlaceOfClassesAndLib() throws IOException {
try (JarFile jarFile = new JarFile(createLayeredJar())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classes"))
.isEqualTo(this.classesPath);
.isEqualTo(this.classesPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo(this.libPath);
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Layers-Index"))
.isEqualTo(this.indexPath + "layers.idx");
.isEqualTo(this.indexPath + "layers.idx");
}
}
@@ -557,7 +559,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
dependencies.intoLayer("my-deps");
});
layered.getLayerOrder()
.set(List.of("my-deps", "my-internal-deps", "my-snapshot-deps", "resources", "application"));
.set(List.of("my-deps", "my-internal-deps", "my-snapshot-deps", "resources", "application"));
});
try (JarFile jarFile = new JarFile(jar)) {
List<String> entryNames = getEntryNames(jar);
@@ -607,7 +609,7 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
List<String> entryNames = getEntryNames(
createLayeredJar((configuration) -> configuration.getIncludeLayerTools().set(false)));
assertThat(entryNames)
.doesNotContain(this.indexPath + "layers/dependencies/lib/spring-boot-jarmode-layertools.jar");
.doesNotContain(this.indexPath + "layers/dependencies/lib/spring-boot-jarmode-layertools.jar");
}
protected File jarFile(String name) throws IOException {
@@ -718,11 +720,11 @@ abstract class AbstractBootArchiveTests<T extends Jar & BootArchive> {
Set<ResolvedArtifact> artifacts = new LinkedHashSet<>();
artifacts.add(mockLibraryArtifact("first-library.jar", "com.example", "first-library", "1.0.0"));
artifacts.add(mockLibraryArtifact("second-library.jar", "com.example", "second-library", "1.0.0"));
artifacts.add(
mockLibraryArtifact("third-library-SNAPSHOT.jar", "com.example", "third-library", "1.0.0.SNAPSHOT"));
artifacts
.add(mockLibraryArtifact("third-library-SNAPSHOT.jar", "com.example", "third-library", "1.0.0.SNAPSHOT"));
artifacts.add(mockLibraryArtifact("fourth-library.jar", "com.example", "fourth-library", "1.0.0"));
artifacts
.add(mockProjectArtifact("first-project-library.jar", "com.example", "first-project-library", "1.0.0"));
.add(mockProjectArtifact("first-project-library.jar", "com.example", "first-project-library", "1.0.0"));
artifacts.add(mockProjectArtifact("second-project-library-SNAPSHOT.jar", "com.example",
"second-project-library", "1.0.0.SNAPSHOT"));
ResolvedConfiguration resolvedConfiguration = mock(ResolvedConfiguration.class);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -90,7 +90,7 @@ class BootBuildImageIntegrationTests {
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
assertThat(buildLibs.listFiles())
.containsExactly(new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"));
.containsExactly(new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"));
removeImages(projectName);
}
@@ -106,7 +106,7 @@ class BootBuildImageIntegrationTests {
assertThat(result.getOutput()).contains("---> Test Info buildpack done");
File buildLibs = new File(this.gradleBuild.getProjectDir(), "build/libs");
assertThat(buildLibs.listFiles())
.containsExactly(new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"));
.containsExactly(new File(buildLibs, this.gradleBuild.getProjectDir().getName() + ".war"));
removeImages(projectName);
}
@@ -172,7 +172,7 @@ class BootBuildImageIntegrationTests {
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
assertThat(result.getOutput()).contains("---> Test Info buildpack building")
.contains("---> Test Info buildpack done");
.contains("---> Test Info buildpack done");
removeImages(projectName);
}
@@ -214,7 +214,7 @@ class BootBuildImageIntegrationTests {
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("docker.io/library/" + projectName);
assertThat(result.getOutput()).contains("---> Test Info buildpack building")
.contains("---> Test Info buildpack done");
.contains("---> Test Info buildpack done");
removeImages(projectName);
}
@@ -307,7 +307,7 @@ class BootBuildImageIntegrationTests {
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage", "--imageName=example/Invalid-Image-Name");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.FAILED);
assertThat(result.getOutput()).containsPattern("Unable to parse image reference")
.containsPattern("example/Invalid-Image-Name");
.containsPattern("example/Invalid-Image-Name");
}
@TestTemplate
@@ -326,7 +326,7 @@ class BootBuildImageIntegrationTests {
BuildResult result = this.gradleBuild.buildAndFail("bootBuildImage");
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.FAILED);
assertThat(result.getOutput()).containsPattern("Unable to parse image reference")
.containsPattern("example/Invalid-Tag-Name");
.containsPattern("example/Invalid-Tag-Name");
}
@TestTemplate
@@ -362,17 +362,18 @@ class BootBuildImageIntegrationTests {
private void writeLongNameResource() throws IOException {
StringBuilder name = new StringBuilder();
new Random().ints('a', 'z' + 1).limit(128).forEach((i) -> name.append((char) i));
Path path = this.gradleBuild.getProjectDir().toPath()
.resolve(Paths.get("src", "main", "resources", name.toString()));
Path path = this.gradleBuild.getProjectDir()
.toPath()
.resolve(Paths.get("src", "main", "resources", name.toString()));
Files.createDirectories(path.getParent());
Files.createFile(path);
}
private void writeBuildpackContent() throws IOException {
FileAttribute<Set<PosixFilePermission>> dirAttribute = PosixFilePermissions
.asFileAttribute(PosixFilePermissions.fromString("rwxr-xr-x"));
.asFileAttribute(PosixFilePermissions.fromString("rwxr-xr-x"));
FileAttribute<Set<PosixFilePermission>> execFileAttribute = PosixFilePermissions
.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx"));
.asFileAttribute(PosixFilePermissions.fromString("rwxrwxrwx"));
File buildpackDir = new File(this.gradleBuild.getProjectDir(), "buildpack/hello-world");
Files.createDirectories(buildpackDir.toPath(), dirAttribute);
File binDir = new File(buildpackDir, "bin");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -53,7 +53,7 @@ class BootBuildImageRegistryIntegrationTests {
@Container
static final RegistryContainer registry = new RegistryContainer().withStartupAttempts(5)
.withStartupTimeout(Duration.ofMinutes(3));
.withStartupTimeout(Duration.ofMinutes(3));
String registryAddress;
@@ -72,9 +72,10 @@ class BootBuildImageRegistryIntegrationTests {
String imageName = this.registryAddress + "/" + repoName;
BuildResult result = this.gradleBuild.build("bootBuildImage", "--imageName=" + imageName);
assertThat(result.task(":bootBuildImage").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("Building image").contains("Successfully built image")
.contains("Pushing image '" + imageName + ":latest" + "'")
.contains("Pushed image '" + imageName + ":latest" + "'");
assertThat(result.getOutput()).contains("Building image")
.contains("Successfully built image")
.contains("Pushing image '" + imageName + ":latest" + "'")
.contains("Pushed image '" + imageName + ":latest" + "'");
ImageReference imageReference = ImageReference.of(imageName);
Image pulledImage = new DockerApi().image().pull(imageReference, UpdateListener.none());
assertThat(pulledImage).isNotNull();

View File

@@ -103,8 +103,9 @@ class BootBuildImageTests {
void whenIndividualEntriesAreAddedToTheEnvironmentThenTheyAreIncludedInTheRequest() {
this.buildImage.getEnvironment().put("ALPHA", "a");
this.buildImage.getEnvironment().put("BRAVO", "b");
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a").containsEntry("BRAVO", "b")
.hasSize(2);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a")
.containsEntry("BRAVO", "b")
.hasSize(2);
}
@Test
@@ -113,8 +114,9 @@ class BootBuildImageTests {
environment.put("ALPHA", "a");
environment.put("BRAVO", "b");
this.buildImage.getEnvironment().putAll(environment);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a").containsEntry("BRAVO", "b")
.hasSize(2);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a")
.containsEntry("BRAVO", "b")
.hasSize(2);
}
@Test
@@ -123,8 +125,9 @@ class BootBuildImageTests {
environment.put("ALPHA", "a");
environment.put("BRAVO", "b");
this.buildImage.getEnvironment().set(environment);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a").containsEntry("BRAVO", "b")
.hasSize(2);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a")
.containsEntry("BRAVO", "b")
.hasSize(2);
}
@Test
@@ -134,8 +137,9 @@ class BootBuildImageTests {
environment.put("BRAVO", "b");
this.buildImage.getEnvironment().put("C", "Charlie");
this.buildImage.getEnvironment().set(environment);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a").containsEntry("BRAVO", "b")
.hasSize(2);
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a")
.containsEntry("BRAVO", "b")
.hasSize(2);
}
@Test
@@ -206,23 +210,23 @@ class BootBuildImageTests {
@Test
void whenBuildpacksAreConfiguredThenRequestHasBuildpacks() {
this.buildImage.getBuildpacks().set(Arrays.asList("example/buildpack1", "example/buildpack2"));
assertThat(this.buildImage.createRequest().getBuildpacks()).containsExactly(
BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
assertThat(this.buildImage.createRequest().getBuildpacks())
.containsExactly(BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
}
@Test
void whenEntriesAreAddedToBuildpacksThenRequestHasBuildpacks() {
this.buildImage.getBuildpacks().addAll(Arrays.asList("example/buildpack1", "example/buildpack2"));
assertThat(this.buildImage.createRequest().getBuildpacks()).containsExactly(
BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
assertThat(this.buildImage.createRequest().getBuildpacks())
.containsExactly(BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
}
@Test
void whenIndividualEntriesAreAddedToBuildpacksThenRequestHasBuildpacks() {
this.buildImage.getBuildpacks().add("example/buildpack1");
this.buildImage.getBuildpacks().add("example/buildpack2");
assertThat(this.buildImage.createRequest().getBuildpacks()).containsExactly(
BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
assertThat(this.buildImage.createRequest().getBuildpacks())
.containsExactly(BuildpackReference.of("example/buildpack1"), BuildpackReference.of("example/buildpack2"));
}
@Test
@@ -234,15 +238,15 @@ class BootBuildImageTests {
void whenBindingsAreConfiguredThenRequestHasBindings() {
this.buildImage.getBindings().set(Arrays.asList("host-src:container-dest:ro", "volume-name:container-dest:rw"));
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
@Test
void whenEntriesAreAddedToBindingsThenRequestHasBindings() {
this.buildImage.getBindings()
.addAll(Arrays.asList("host-src:container-dest:ro", "volume-name:container-dest:rw"));
.addAll(Arrays.asList("host-src:container-dest:ro", "volume-name:container-dest:rw"));
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
@Test
@@ -250,7 +254,7 @@ class BootBuildImageTests {
this.buildImage.getBindings().add("host-src:container-dest:ro");
this.buildImage.getBindings().add("volume-name:container-dest:rw");
assertThat(this.buildImage.createRequest().getBindings())
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
.containsExactly(Binding.of("host-src:container-dest:ro"), Binding.of("volume-name:container-dest:rw"));
}
@Test
@@ -267,15 +271,15 @@ class BootBuildImageTests {
@Test
void whenTagsAreConfiguredThenRequestHasTags() {
this.buildImage.getTags()
.set(Arrays.asList("my-app:latest", "example.com/my-app:0.0.1-SNAPSHOT", "example.com/my-app:latest"));
.set(Arrays.asList("my-app:latest", "example.com/my-app:0.0.1-SNAPSHOT", "example.com/my-app:latest"));
assertThat(this.buildImage.createRequest().getTags()).containsExactly(ImageReference.of("my-app:latest"),
ImageReference.of("example.com/my-app:0.0.1-SNAPSHOT"), ImageReference.of("example.com/my-app:latest"));
}
@Test
void whenEntriesAreAddedToTagsThenRequestHasTags() {
this.buildImage.getTags().addAll(
Arrays.asList("my-app:latest", "example.com/my-app:0.0.1-SNAPSHOT", "example.com/my-app:latest"));
this.buildImage.getTags()
.addAll(Arrays.asList("my-app:latest", "example.com/my-app:0.0.1-SNAPSHOT", "example.com/my-app:latest"));
assertThat(this.buildImage.createRequest().getTags()).containsExactly(ImageReference.of("my-app:latest"),
ImageReference.of("example.com/my-app:0.0.1-SNAPSHOT"), ImageReference.of("example.com/my-app:latest"));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -47,7 +47,7 @@ class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
void whenAResolvableCopyOfAnUnresolvableConfigurationIsResolvedThenResolutionSucceeds() {
BuildResult build = this.gradleBuild.build("resolveResolvableCopyOfUnresolvableConfiguration");
assertThat(build.task(":resolveResolvableCopyOfUnresolvableConfiguration").getOutcome())
.isEqualTo(TaskOutcome.SUCCESS);
.isEqualTo(TaskOutcome.SUCCESS);
}
@TestTemplate

View File

@@ -99,7 +99,7 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
void classpathIndexPointsToBootInfLibs() throws IOException {
try (JarFile jarFile = new JarFile(createPopulatedJar())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
.isEqualTo("BOOT-INF/classpath.idx");
.isEqualTo("BOOT-INF/classpath.idx");
assertThat(entryLines(jarFile, "BOOT-INF/classpath.idx")).containsExactly(
"- \"BOOT-INF/lib/first-library.jar\"", "- \"BOOT-INF/lib/second-library.jar\"",
"- \"BOOT-INF/lib/third-library-SNAPSHOT.jar\"", "- \"BOOT-INF/lib/fourth-library.jar\"",
@@ -208,7 +208,7 @@ class BootJarTests extends AbstractBootArchiveTests<BootJar> {
void javaVersionIsWrittenToManifest() throws IOException {
try (JarFile jarFile = new JarFile(createPopulatedJar())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Build-Jdk-Spec"))
.isEqualTo(JavaVersion.VERSION_17.getMajorVersion());
.isEqualTo(JavaVersion.VERSION_17.getMajorVersion());
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -117,7 +117,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
getTask().providedClasspath(jarFile("provided-library.jar"));
executeTask();
assertThat(getEntryNames(getTask().getArchiveFile().get().getAsFile()))
.containsSubsequence("WEB-INF/lib/library.jar", "WEB-INF/lib-provided/provided-library.jar");
.containsSubsequence("WEB-INF/lib/library.jar", "WEB-INF/lib-provided/provided-library.jar");
}
@Test
@@ -135,7 +135,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
void classpathIndexPointsToWebInfLibs() throws IOException {
try (JarFile jarFile = new JarFile(createPopulatedJar())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Spring-Boot-Classpath-Index"))
.isEqualTo("WEB-INF/classpath.idx");
.isEqualTo("WEB-INF/classpath.idx");
assertThat(entryLines(jarFile, "WEB-INF/classpath.idx")).containsExactly(
"- \"WEB-INF/lib/first-library.jar\"", "- \"WEB-INF/lib/second-library.jar\"",
"- \"WEB-INF/lib/third-library-SNAPSHOT.jar\"", "- \"WEB-INF/lib/fourth-library.jar\"",
@@ -148,7 +148,7 @@ class BootWarTests extends AbstractBootArchiveTests<BootWar> {
void javaVersionIsWrittenToManifest() throws IOException {
try (JarFile jarFile = new JarFile(createPopulatedJar())) {
assertThat(jarFile.getManifest().getMainAttributes().getValue("Build-Jdk-Spec"))
.isEqualTo(JavaVersion.VERSION_17.getMajorVersion());
.isEqualTo(JavaVersion.VERSION_17.getMajorVersion());
}
}

View File

@@ -43,8 +43,11 @@ class DockerSpecTests {
@BeforeEach
void prepareDockerSpec(@TempDir File temp) {
this.dockerSpec = GradleProjectBuilder.builder().withProjectDir(temp).build().getObjects()
.newInstance(DockerSpec.class);
this.dockerSpec = GradleProjectBuilder.builder()
.withProjectDir(temp)
.build()
.getObjects()
.newInstance(DockerSpec.class);
}
@Test
@@ -53,8 +56,10 @@ class DockerSpecTests {
assertThat(dockerConfiguration.getHost()).isNull();
assertThat(dockerConfiguration.getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
.contains("\"username\" : \"\"")
.contains("\"password\" : \"\"")
.contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@@ -70,8 +75,10 @@ class DockerSpecTests {
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
.contains("\"username\" : \"\"")
.contains("\"password\" : \"\"")
.contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@@ -85,8 +92,10 @@ class DockerSpecTests {
assertThat(dockerConfiguration.isBindHostToBuilder()).isFalse();
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
.contains("\"username\" : \"\"")
.contains("\"password\" : \"\"")
.contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@@ -101,8 +110,10 @@ class DockerSpecTests {
assertThat(dockerConfiguration.isBindHostToBuilder()).isTrue();
assertThat(this.dockerSpec.asDockerConfiguration().getBuilderRegistryAuthentication()).isNull();
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"\"").contains("\"password\" : \"\"").contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
.contains("\"username\" : \"\"")
.contains("\"password\" : \"\"")
.contains("\"email\" : \"\"")
.contains("\"serveraddress\" : \"\"");
}
@Test
@@ -121,13 +132,15 @@ class DockerSpecTests {
});
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"user1\"").contains("\"password\" : \"secret1\"")
.contains("\"email\" : \"docker1@example.com\"")
.contains("\"serveraddress\" : \"https://docker1.example.com\"");
.contains("\"username\" : \"user1\"")
.contains("\"password\" : \"secret1\"")
.contains("\"email\" : \"docker1@example.com\"")
.contains("\"serveraddress\" : \"https://docker1.example.com\"");
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"username\" : \"user2\"").contains("\"password\" : \"secret2\"")
.contains("\"email\" : \"docker2@example.com\"")
.contains("\"serveraddress\" : \"https://docker2.example.com\"");
.contains("\"username\" : \"user2\"")
.contains("\"password\" : \"secret2\"")
.contains("\"email\" : \"docker2@example.com\"")
.contains("\"serveraddress\" : \"https://docker2.example.com\"");
assertThat(this.dockerSpec.asDockerConfiguration().getHost()).isNull();
}
@@ -139,7 +152,7 @@ class DockerSpecTests {
registry.getEmail().set("docker1@example.com");
});
assertThatExceptionOfType(GradleException.class).isThrownBy(this.dockerSpec::asDockerConfiguration)
.withMessageContaining("Invalid Docker builder registry configuration");
.withMessageContaining("Invalid Docker builder registry configuration");
}
@Test
@@ -150,7 +163,7 @@ class DockerSpecTests {
registry.getEmail().set("docker2@example.com");
});
assertThatExceptionOfType(GradleException.class).isThrownBy(this.dockerSpec::asDockerConfiguration)
.withMessageContaining("Invalid Docker publish registry configuration");
.withMessageContaining("Invalid Docker publish registry configuration");
}
@Test
@@ -159,9 +172,9 @@ class DockerSpecTests {
this.dockerSpec.publishRegistry((registry) -> registry.getToken().set("token2"));
DockerConfiguration dockerConfiguration = this.dockerSpec.asDockerConfiguration();
assertThat(decoded(dockerConfiguration.getBuilderRegistryAuthentication().getAuthHeader()))
.contains("\"identitytoken\" : \"token1\"");
.contains("\"identitytoken\" : \"token1\"");
assertThat(decoded(dockerConfiguration.getPublishRegistryAuthentication().getAuthHeader()))
.contains("\"identitytoken\" : \"token2\"");
.contains("\"identitytoken\" : \"token2\"");
}
@Test
@@ -172,7 +185,7 @@ class DockerSpecTests {
registry.getToken().set("token");
});
assertThatExceptionOfType(GradleException.class).isThrownBy(this.dockerSpec::asDockerConfiguration)
.withMessageContaining("Invalid Docker builder registry configuration");
.withMessageContaining("Invalid Docker builder registry configuration");
}
String decoded(String value) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2021 the original author or authors.
* Copyright 2012-2023 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.
@@ -44,7 +44,10 @@ class MavenPublishingIntegrationTests {
assertThat(result.task(":publish").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("jar")).isFile();
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName()).version("1.0").noPackaging().noDependencies());
.artifactId(this.gradleBuild.getProjectDir().getName())
.version("1.0")
.noPackaging()
.noDependencies());
}
@TestTemplate
@@ -52,9 +55,11 @@ class MavenPublishingIntegrationTests {
BuildResult result = this.gradleBuild.build("publish");
assertThat(result.task(":publish").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(artifactWithSuffix("war")).isFile();
assertThat(artifactWithSuffix("pom"))
.is(pomWith().groupId("com.example").artifactId(this.gradleBuild.getProjectDir().getName())
.version("1.0").packaging("war").noDependencies());
assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example")
.artifactId(this.gradleBuild.getProjectDir().getName())
.version("1.0")
.packaging("war")
.noDependencies());
}
private File artifactWithSuffix(String suffix) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2012-2022 the original author or authors.
* Copyright 2012-2023 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.
@@ -87,7 +87,7 @@ class BootRunIntegrationTests {
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput())
.contains("Main class name = com.example.bootrun.classpath.BootRunClasspathApplication");
.contains("Main class name = com.example.bootrun.classpath.BootRunClasspathApplication");
}
@TestTemplate
@@ -111,8 +111,9 @@ class BootRunIntegrationTests {
copyJvmArgsApplication();
BuildResult result = this.gradleBuild.build("bootRun");
assertThat(result.task(":bootRun").getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("-Dcom.bar=baz").contains("-Dcom.foo=bar")
.contains("-XX:TieredStopAtLevel=1");
assertThat(result.getOutput()).contains("-Dcom.bar=baz")
.contains("-Dcom.foo=bar")
.contains("-XX:TieredStopAtLevel=1");
}
@TestTemplate