Skip to content

Commit 3fc98eb

Browse files
committed
Allow modules to contribute to Devtools' default properties
Closes gh-
1 parent dee3dc4 commit 3fc98eb

File tree

19 files changed

+89
-73
lines changed

19 files changed

+89
-73
lines changed

buildSrc/src/main/java/org/springframework/boot/build/devtools/DocumentDevtoolsPropertyDefaults.java

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,24 @@
1616

1717
package org.springframework.boot.build.devtools;
1818

19-
import java.io.FileInputStream;
19+
import java.io.File;
2020
import java.io.FileNotFoundException;
2121
import java.io.FileWriter;
2222
import java.io.IOException;
2323
import java.io.PrintWriter;
24-
import java.util.HashMap;
2524
import java.util.Map;
2625
import java.util.Properties;
2726
import java.util.TreeMap;
27+
import java.util.jar.JarFile;
28+
import java.util.zip.ZipEntry;
2829

2930
import org.gradle.api.DefaultTask;
30-
import org.gradle.api.artifacts.Configuration;
3131
import org.gradle.api.file.FileCollection;
3232
import org.gradle.api.file.RegularFileProperty;
3333
import org.gradle.api.tasks.InputFiles;
3434
import org.gradle.api.tasks.OutputFile;
35+
import org.gradle.api.tasks.PathSensitive;
36+
import org.gradle.api.tasks.PathSensitivity;
3537
import org.gradle.api.tasks.TaskAction;
3638

3739
/**
@@ -41,46 +43,59 @@
4143
*/
4244
public abstract class DocumentDevtoolsPropertyDefaults extends DefaultTask {
4345

44-
private final Configuration devtools;
46+
private FileCollection defaults;
4547

4648
public DocumentDevtoolsPropertyDefaults() {
47-
this.devtools = getProject().getConfigurations().create("devtools");
4849
getOutputFile().convention(getProject().getLayout()
4950
.getBuildDirectory()
5051
.file("generated/docs/using/devtools-property-defaults.adoc"));
51-
Map<String, String> dependency = new HashMap<>();
52-
dependency.put("path", ":module:spring-boot-devtools");
53-
dependency.put("configuration", "propertyDefaults");
54-
this.devtools.getDependencies().add(getProject().getDependencies().project(dependency));
5552
}
5653

5754
@InputFiles
58-
public FileCollection getDevtools() {
59-
return this.devtools;
55+
@PathSensitive(PathSensitivity.RELATIVE)
56+
public FileCollection getDefaults() {
57+
return this.defaults;
58+
}
59+
60+
public void setDefaults(FileCollection defaults) {
61+
this.defaults = defaults;
6062
}
6163

6264
@OutputFile
6365
public abstract RegularFileProperty getOutputFile();
6466

6567
@TaskAction
6668
void documentPropertyDefaults() throws IOException {
67-
Map<String, String> properties = loadProperties();
68-
documentProperties(properties);
69+
Map<String, String> propertyDefaults = loadPropertyDefaults();
70+
documentPropertyDefaults(propertyDefaults);
6971
}
7072

71-
private Map<String, String> loadProperties() throws IOException, FileNotFoundException {
73+
private Map<String, String> loadPropertyDefaults() throws IOException, FileNotFoundException {
7274
Properties properties = new Properties();
73-
Map<String, String> sortedProperties = new TreeMap<>();
74-
try (FileInputStream stream = new FileInputStream(this.devtools.getSingleFile())) {
75-
properties.load(stream);
76-
for (String name : properties.stringPropertyNames()) {
77-
sortedProperties.put(name, properties.getProperty(name));
75+
Map<String, String> propertyDefaults = new TreeMap<>();
76+
for (File contribution : this.defaults.getFiles()) {
77+
if (contribution.isFile()) {
78+
try (JarFile jar = new JarFile(contribution)) {
79+
ZipEntry entry = jar.getEntry("META-INF/spring-devtools.properties");
80+
if (entry != null) {
81+
properties.load(jar.getInputStream(entry));
82+
}
83+
}
84+
}
85+
else if (contribution.exists()) {
86+
throw new IllegalStateException(
87+
"Unexpected Devtools default properties contribution from '" + contribution + "'");
88+
}
89+
}
90+
for (String name : properties.stringPropertyNames()) {
91+
if (name.startsWith("defaults.")) {
92+
propertyDefaults.put(name.substring("defaults.".length()), properties.getProperty(name));
7893
}
7994
}
80-
return sortedProperties;
95+
return propertyDefaults;
8196
}
8297

83-
private void documentProperties(Map<String, String> properties) throws IOException {
98+
private void documentPropertyDefaults(Map<String, String> properties) throws IOException {
8499
try (PrintWriter writer = new PrintWriter(new FileWriter(getOutputFile().getAsFile().get()))) {
85100
writer.println("[cols=\"3,1\"]");
86101
writer.println("|===");
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defaults.spring.template.provider.cache=false
2+
defaults.spring.web.resources.cache.period=0
3+
defaults.spring.web.resources.chain.cache=false
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
defaults.spring.docker.compose.readiness.wait=only-if-started

documentation/spring-boot-docs/build.gradle

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,10 @@ aggregates {
322322
category = Category.DOCUMENTATION
323323
usage = "test-slice-metadata"
324324
}
325+
devtoolsPropertyDefaults {
326+
category = Category.LIBRARY
327+
usage = "java-runtime"
328+
}
325329
}
326330

327331
tasks.register("documentTestSlices", org.springframework.boot.build.test.autoconfigure.DocumentTestSlices) {
@@ -363,7 +367,9 @@ tasks.register("documentConfigurationProperties", org.springframework.boot.build
363367
outputDir = layout.buildDirectory.dir("generated/docs/application-properties")
364368
}
365369

366-
tasks.register("documentDevtoolsPropertyDefaults", org.springframework.boot.build.devtools.DocumentDevtoolsPropertyDefaults) {}
370+
tasks.register("documentDevtoolsPropertyDefaults", org.springframework.boot.build.devtools.DocumentDevtoolsPropertyDefaults) {
371+
defaults = aggregates.devtoolsPropertyDefaults.files
372+
}
367373

368374
tasks.register("runRemoteSpringApplicationExample", org.springframework.boot.build.docs.ApplicationRunner) {
369375
classpath = configurations.remoteSpringApplicationExample

module/spring-boot-devtools/build.gradle

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,6 @@ configurations {
2929
intTestDependencies {
3030
extendsFrom dependencyManagement
3131
}
32-
propertyDefaults
33-
}
34-
35-
artifacts {
36-
propertyDefaults(file("build/resources/main/org/springframework/boot/devtools/env/devtools-property-defaults.properties")) {
37-
builtBy(processResources)
38-
}
3932
}
4033

4134
dependencies {
@@ -60,7 +53,6 @@ dependencies {
6053
intTestImplementation("org.apache.httpcomponents.client5:httpclient5")
6154
intTestImplementation("net.bytebuddy:byte-buddy")
6255

63-
6456
intTestRuntimeOnly("org.springframework:spring-web")
6557

6658
optional(project(":module:spring-boot-jdbc"))

module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsPropertyDefaultsPostProcessor.java

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,8 @@
1616

1717
package org.springframework.boot.devtools.env;
1818

19-
import java.io.IOException;
20-
import java.io.InputStream;
2119
import java.util.Collections;
22-
import java.util.HashMap;
2320
import java.util.Map;
24-
import java.util.Properties;
2521

2622
import org.apache.commons.logging.Log;
2723
import org.jspecify.annotations.Nullable;
@@ -30,6 +26,7 @@
3026
import org.springframework.boot.SpringApplication;
3127
import org.springframework.boot.devtools.logger.DevToolsLogFactory;
3228
import org.springframework.boot.devtools.restart.Restarter;
29+
import org.springframework.boot.devtools.settings.DevToolsSettings;
3330
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
3431
import org.springframework.core.NativeDetector;
3532
import org.springframework.core.Ordered;
@@ -69,7 +66,7 @@ public class DevToolsPropertyDefaultsPostProcessor implements EnvironmentPostPro
6966
PROPERTIES = Collections.emptyMap();
7067
}
7168
else {
72-
PROPERTIES = loadDefaultProperties();
69+
PROPERTIES = DevToolsSettings.get().getPropertyDefaults();
7370
}
7471
}
7572

@@ -133,24 +130,4 @@ private boolean isWebApplication(Environment environment) {
133130
}
134131
}
135132

136-
private static Map<String, Object> loadDefaultProperties() {
137-
Properties properties = new Properties();
138-
try (InputStream stream = DevToolsPropertyDefaultsPostProcessor.class
139-
.getResourceAsStream("devtools-property-defaults.properties")) {
140-
if (stream == null) {
141-
throw new RuntimeException(
142-
"Failed to load devtools-property-defaults.properties because it doesn't exist");
143-
}
144-
properties.load(stream);
145-
}
146-
catch (IOException ex) {
147-
throw new RuntimeException("Failed to load devtools-property-defaults.properties", ex);
148-
}
149-
Map<String, Object> map = new HashMap<>();
150-
for (String name : properties.stringPropertyNames()) {
151-
map.put(name, properties.getProperty(name));
152-
}
153-
return Collections.unmodifiableMap(map);
154-
}
155-
156133
}

module/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/settings/DevToolsSettings.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@
1818

1919
import java.net.URL;
2020
import java.util.ArrayList;
21+
import java.util.Collections;
2122
import java.util.Enumeration;
23+
import java.util.HashMap;
2224
import java.util.LinkedHashMap;
2325
import java.util.List;
2426
import java.util.Map;
@@ -52,14 +54,23 @@ public class DevToolsSettings {
5254

5355
private final List<Pattern> restartExcludePatterns = new ArrayList<>();
5456

57+
private final Map<String, Object> propertyDefaults = new HashMap<>();
58+
5559
DevToolsSettings() {
5660
}
5761

58-
void add(Map<?, ?> properties) {
62+
private void add(Map<?, ?> properties) {
5963
Map<String, Pattern> includes = getPatterns(properties, "restart.include.");
6064
this.restartIncludePatterns.addAll(includes.values());
6165
Map<String, Pattern> excludes = getPatterns(properties, "restart.exclude.");
6266
this.restartExcludePatterns.addAll(excludes.values());
67+
properties.forEach((key, value) -> {
68+
String name = String.valueOf(key);
69+
if (name.startsWith("defaults.")) {
70+
name = name.substring("defaults.".length());
71+
this.propertyDefaults.put(name, value);
72+
}
73+
});
6374
}
6475

6576
private Map<String, Pattern> getPatterns(Map<?, ?> properties, String prefix) {
@@ -82,6 +93,10 @@ public boolean isRestartExclude(URL url) {
8293
return isMatch(url.toString(), this.restartExcludePatterns);
8394
}
8495

96+
public Map<String, Object> getPropertyDefaults() {
97+
return Collections.unmodifiableMap(this.propertyDefaults);
98+
}
99+
85100
private boolean isMatch(String url, List<Pattern> patterns) {
86101
for (Pattern pattern : patterns) {
87102
if (pattern.matcher(url).find()) {

module/spring-boot-devtools/src/main/resources/org/springframework/boot/devtools/env/devtools-property-defaults.properties

Lines changed: 0 additions & 17 deletions
This file was deleted.

module/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/settings/DevToolsSettingsTests.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.File;
2020
import java.io.IOException;
2121
import java.net.URL;
22+
import java.util.Map;
2223

2324
import org.junit.jupiter.api.Test;
2425
import org.junit.jupiter.api.io.TempDir;
@@ -60,6 +61,13 @@ void defaultIncludePatterns(@TempDir File tempDir) throws Exception {
6061
assertThat(settings.isRestartExclude(makeUrl(tempDir, "spring-boot-starter-some-thing"))).isTrue();
6162
}
6263

64+
@Test
65+
void propertyDefaults() {
66+
DevToolsSettings settings = DevToolsSettings.load(ROOT + "spring-devtools-defaults.properties");
67+
Map<String, Object> propertyDefaults = settings.getPropertyDefaults();
68+
assertThat(propertyDefaults).containsExactlyEntriesOf(Map.of("com.example.a", "true", "com.example.b", "17"));
69+
}
70+
6371
private URL makeUrl(File file, String name) throws IOException {
6472
file = new File(file, name);
6573
file = new File(file, "build");
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
defaults.com.example.a=true
2+
defaults.com.example.b=17
3+

0 commit comments

Comments
 (0)