Fix missing test slice configuration

Test slices are now longer registered in spring.factories, but
TestSliceMetadata still looked there for them to generate documentation.
Fixed this so that TestSliceMetadata now looks in the right places for
test slices.

See gh-29873
pull/29911/head
Moritz Halbritter 3 years ago
parent 940558c2a6
commit 2afa02c856

@ -1,5 +1,5 @@
/* /*
* Copyright 2012-2021 the original author or authors. * Copyright 2012-2022 the original author or authors.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -21,11 +21,14 @@ import java.io.FileReader;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Reader; import java.io.Reader;
import java.io.UncheckedIOException;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties; import java.util.Properties;
import java.util.SortedSet; import java.util.SortedSet;
import java.util.TreeSet; import java.util.TreeSet;
@ -102,6 +105,8 @@ public class TestSliceMetadata extends DefaultTask {
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(classLoader); MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(classLoader);
Properties springFactories = readSpringFactories( Properties springFactories = readSpringFactories(
new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories")); new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories"));
readTestSlicesDirectory(springFactories,
new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring-boot/"));
for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) { for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) {
addTestSlices(testSlices, classesDir, metadataReaderFactory, springFactories); addTestSlices(testSlices, classesDir, metadataReaderFactory, springFactories);
} }
@ -109,6 +114,45 @@ public class TestSliceMetadata extends DefaultTask {
return testSlices; return testSlices;
} }
/**
* Reads files from the given directory and puts them in springFactories. The key is
* the file name, the value is the file contents, split by line, delimited with comma.
*
* This is done to mimic the spring.factories structure.
* @param springFactories spring.factories parsed as properties
* @param directory directory to scan
*/
private void readTestSlicesDirectory(Properties springFactories, File directory) {
File[] files = directory.listFiles();
if (files == null) {
return;
}
for (File file : files) {
try {
List<String> lines = removeComments(Files.readAllLines(file.toPath()));
springFactories.setProperty(file.getName(), StringUtils.collectionToCommaDelimitedString(lines));
}
catch (IOException ex) {
throw new UncheckedIOException("Failed to read file " + file, ex);
}
}
}
private List<String> removeComments(List<String> lines) {
List<String> result = new ArrayList<>();
for (String line : lines) {
int commentIndex = line.indexOf('#');
if (commentIndex > -1) {
line = line.substring(0, commentIndex);
}
line = line.trim();
if (!line.isEmpty()) {
result.add(line);
}
}
return result;
}
private URL toURL(File file) { private URL toURL(File file) {
try { try {
return file.toURI().toURL(); return file.toURI().toURL();

@ -18,7 +18,7 @@ Additional `@Conditional` annotations are used to constrain when the auto-config
Usually, auto-configuration classes use `@ConditionalOnClass` and `@ConditionalOnMissingBean` annotations. Usually, auto-configuration classes use `@ConditionalOnClass` and `@ConditionalOnMissingBean` annotations.
This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own `@Configuration`. This ensures that auto-configuration applies only when relevant classes are found and when you have not declared your own `@Configuration`.
You can browse the source code of {spring-boot-autoconfigure-module-code}[`spring-boot-autoconfigure`] to see the `@Configuration` classes that Spring provides (see the {spring-boot-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring.factories[`META-INF/spring.factories`] file). You can browse the source code of {spring-boot-autoconfigure-module-code}[`spring-boot-autoconfigure`] to see the `@Configuration` classes that Spring provides (see the {spring-boot-code}/spring-boot-project/spring-boot-autoconfigure/src/main/resources/META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration[`META-INF/spring-boot/org.springframework.boot.autoconfigure.AutoConfiguration`] file).

Loading…
Cancel
Save