Skip to content

Commit f7290b2

Browse files
committed
Merge pull request #17924 from scottmf
* gh-17924: Polish "Make dev tools' home directory configurable" Make dev tools' home directory configurable Closes gh-17924
2 parents 48db35b + 8e7a6ce commit f7290b2

File tree

3 files changed

+89
-18
lines changed

3 files changed

+89
-18
lines changed

spring-boot-project/spring-boot-devtools/src/main/java/org/springframework/boot/devtools/env/DevToolsHomePropertiesPostProcessor.java

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,11 @@
2323
import java.util.Collections;
2424
import java.util.HashSet;
2525
import java.util.List;
26+
import java.util.Map;
27+
import java.util.Properties;
2628
import java.util.Set;
2729
import java.util.function.Function;
30+
import java.util.function.Supplier;
2831

2932
import org.springframework.boot.SpringApplication;
3033
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
@@ -59,6 +62,10 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
5962

6063
private static final Set<PropertySourceLoader> PROPERTY_SOURCE_LOADERS;
6164

65+
private final Properties systemProperties;
66+
67+
private final Map<String, String> environmentVariables;
68+
6269
static {
6370
Set<PropertySourceLoader> propertySourceLoaders = new HashSet<>();
6471
propertySourceLoaders.add(new PropertiesPropertySourceLoader());
@@ -68,6 +75,15 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
6875
PROPERTY_SOURCE_LOADERS = Collections.unmodifiableSet(propertySourceLoaders);
6976
}
7077

78+
public DevToolsHomePropertiesPostProcessor() {
79+
this(System.getenv(), System.getProperties());
80+
}
81+
82+
DevToolsHomePropertiesPostProcessor(Map<String, String> environmentVariables, Properties systemProperties) {
83+
this.environmentVariables = environmentVariables;
84+
this.systemProperties = systemProperties;
85+
}
86+
7187
@Override
7288
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
7389
if (DevToolsEnablementDeducer.shouldEnable(Thread.currentThread())) {
@@ -122,9 +138,18 @@ private boolean canLoadFileExtension(PropertySourceLoader loader, String name) {
122138
}
123139

124140
protected File getHomeDirectory() {
125-
String home = System.getProperty("user.home");
126-
if (StringUtils.hasLength(home)) {
127-
return new File(home);
141+
return getHomeDirectory(() -> this.environmentVariables.get("SPRING_DEVTOOLS_HOME"),
142+
() -> this.systemProperties.getProperty("spring.devtools.home"),
143+
() -> this.systemProperties.getProperty("user.home"));
144+
}
145+
146+
@SafeVarargs
147+
private final File getHomeDirectory(Supplier<String>... pathSuppliers) {
148+
for (Supplier<String> pathSupplier : pathSuppliers) {
149+
String path = pathSupplier.get();
150+
if (StringUtils.hasText(path)) {
151+
return new File(path);
152+
}
128153
}
129154
return null;
130155
}

spring-boot-project/spring-boot-devtools/src/test/java/org/springframework/boot/devtools/env/DevToolsHomePropertiesPostProcessorTests.java

Lines changed: 58 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@
2121
import java.io.IOException;
2222
import java.io.OutputStream;
2323
import java.nio.file.Files;
24+
import java.util.Collections;
25+
import java.util.Map;
2426
import java.util.Properties;
2527

2628
import org.junit.jupiter.api.BeforeEach;
@@ -47,9 +49,12 @@ class DevToolsHomePropertiesPostProcessorTests {
4749

4850
private File home;
4951

52+
private File customHome;
53+
5054
@BeforeEach
5155
void setup(@TempDir File tempDir) {
52-
this.home = tempDir;
56+
this.home = new File(tempDir, "default-home");
57+
this.customHome = new File(tempDir, "custom-home");
5358
this.configDir = this.home + "/.config/spring-boot/";
5459
new File(this.configDir).mkdirs();
5560
}
@@ -63,6 +68,29 @@ void loadsPropertiesFromHomeDirectoryUsingProperties() throws Exception {
6368
assertThat(environment.getProperty("abc")).isEqualTo("def");
6469
}
6570

71+
@Test
72+
void loadsPropertiesFromCustomHomeDirectorySetUsingSystemProperty() throws Exception {
73+
Properties properties = new Properties();
74+
properties.put("uvw", "xyz");
75+
writeFile(properties, this.customHome, ".config/spring-boot/spring-boot-devtools.properties");
76+
Properties systemProperties = new Properties();
77+
systemProperties.setProperty("spring.devtools.home", this.customHome.getAbsolutePath());
78+
ConfigurableEnvironment environment = getPostProcessedEnvironment(systemProperties);
79+
assertThat(environment.getProperty("uvw")).isEqualTo("xyz");
80+
}
81+
82+
@Test
83+
void loadsPropertiesFromCustomHomeDirectorySetUsingEnvironmentVariable() throws Exception {
84+
Properties properties = new Properties();
85+
properties.put("uvw", "xyz");
86+
writeFile(properties, this.customHome, ".config/spring-boot/spring-boot-devtools.properties");
87+
Properties systemProperties = new Properties();
88+
systemProperties.setProperty("spring.devtools.home", this.customHome.getAbsolutePath());
89+
ConfigurableEnvironment environment = getPostProcessedEnvironment(
90+
Collections.singletonMap("SPRING_DEVTOOLS_HOME", this.customHome.getAbsolutePath()));
91+
assertThat(environment.getProperty("uvw")).isEqualTo("xyz");
92+
}
93+
6694
@Test
6795
void loadsPropertiesFromConfigDirectoryUsingProperties() throws Exception {
6896
Properties properties = new Properties();
@@ -151,15 +179,39 @@ void ignoresMissingHomeProperties() throws Exception {
151179
assertThat(environment.getProperty("abc")).isNull();
152180
}
153181

154-
private void writeFile(Properties properties, String s) throws IOException {
155-
OutputStream out = new FileOutputStream(new File(this.home, s));
156-
properties.store(out, null);
157-
out.close();
182+
private void writeFile(Properties properties, String path) throws IOException {
183+
writeFile(properties, this.home, path);
184+
}
185+
186+
private void writeFile(Properties properties, File home, String path) throws IOException {
187+
File file = new File(home, path);
188+
file.getParentFile().mkdirs();
189+
try (OutputStream out = new FileOutputStream(file)) {
190+
properties.store(out, null);
191+
}
158192
}
159193

160194
private ConfigurableEnvironment getPostProcessedEnvironment() throws Exception {
195+
return getPostProcessedEnvironment(null, null);
196+
}
197+
198+
private ConfigurableEnvironment getPostProcessedEnvironment(Properties systemProperties) throws Exception {
199+
return getPostProcessedEnvironment(null, systemProperties);
200+
}
201+
202+
private ConfigurableEnvironment getPostProcessedEnvironment(Map<String, String> env) throws Exception {
203+
return getPostProcessedEnvironment(env, null);
204+
}
205+
206+
private ConfigurableEnvironment getPostProcessedEnvironment(Map<String, String> env, Properties systemProperties)
207+
throws Exception {
208+
if (systemProperties == null) {
209+
systemProperties = new Properties();
210+
systemProperties.setProperty("user.home", this.home.getAbsolutePath());
211+
}
161212
ConfigurableEnvironment environment = new MockEnvironment();
162-
MockDevToolHomePropertiesPostProcessor postProcessor = new MockDevToolHomePropertiesPostProcessor();
213+
DevToolsHomePropertiesPostProcessor postProcessor = new DevToolsHomePropertiesPostProcessor(
214+
(env != null) ? env : Collections.emptyMap(), systemProperties);
163215
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, null));
164216
return environment;
165217
}
@@ -170,13 +222,4 @@ protected void runPostProcessor(Runnable runnable) throws Exception {
170222
thread.join();
171223
}
172224

173-
private class MockDevToolHomePropertiesPostProcessor extends DevToolsHomePropertiesPostProcessor {
174-
175-
@Override
176-
protected File getHomeDirectory() {
177-
return DevToolsHomePropertiesPostProcessorTests.this.home;
178-
}
179-
180-
}
181-
182225
}

spring-boot-project/spring-boot-docs/src/docs/asciidoc/using/devtools.adoc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,9 @@ For example, to configure restart to always use a <<using#using.devtools.restart
285285
trigger-file: ".reloadtrigger"
286286
----
287287

288+
By default, `$HOME` is the user's home directory.
289+
To customize this location, set the `SPRING_DEVTOOLS_HOME` environment variable or the `spring.devtools.home` system property.
290+
288291
NOTE: If devtools configuration files are not found in `$HOME/.config/spring-boot`, the root of the `$HOME` directory is searched for the presence of a `.spring-boot-devtools.properties` file.
289292
This allows you to share the devtools global configuration with applications that are on an older version of Spring Boot that does not support the `$HOME/.config/spring-boot` location.
290293

0 commit comments

Comments
 (0)