From 2afa02c856194192f5ade069d82d1703d48d768f Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Fri, 18 Feb 2022 14:49:07 +0100 Subject: [PATCH] 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 --- .../test/autoconfigure/TestSliceMetadata.java | 46 ++++++++++++++++++- .../developing-auto-configuration.adoc | 2 +- 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java b/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java index 41a31f4821..958e052462 100644 --- a/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java +++ b/buildSrc/src/main/java/org/springframework/boot/build/test/autoconfigure/TestSliceMetadata.java @@ -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"); * 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.IOException; import java.io.Reader; +import java.io.UncheckedIOException; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Properties; import java.util.SortedSet; import java.util.TreeSet; @@ -102,6 +105,8 @@ public class TestSliceMetadata extends DefaultTask { MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory(classLoader); Properties springFactories = readSpringFactories( new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring.factories")); + readTestSlicesDirectory(springFactories, + new File(this.sourceSet.getOutput().getResourcesDir(), "META-INF/spring-boot/")); for (File classesDir : this.sourceSet.getOutput().getClassesDirs()) { addTestSlices(testSlices, classesDir, metadataReaderFactory, springFactories); } @@ -109,6 +114,45 @@ public class TestSliceMetadata extends DefaultTask { 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 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 removeComments(List lines) { + List 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) { try { return file.toURI().toURL(); diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc index d009c2b3c6..1c72edbb68 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/features/developing-auto-configuration.adoc @@ -18,7 +18,7 @@ Additional `@Conditional` annotations are used to constrain when the auto-config 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`. -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).