Polish "Make dev tools' home directory configurable"
See gh-17924
This commit is contained in:
parent
b9dbfad473
commit
8e7a6ceb44
|
|
@ -23,8 +23,11 @@ import java.util.Arrays;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import org.springframework.boot.SpringApplication;
|
import org.springframework.boot.SpringApplication;
|
||||||
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
|
import org.springframework.boot.devtools.system.DevToolsEnablementDeducer;
|
||||||
|
|
@ -59,6 +62,10 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
|
|
||||||
private static final Set<PropertySourceLoader> PROPERTY_SOURCE_LOADERS;
|
private static final Set<PropertySourceLoader> PROPERTY_SOURCE_LOADERS;
|
||||||
|
|
||||||
|
private final Properties systemProperties;
|
||||||
|
|
||||||
|
private final Map<String, String> environmentVariables;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
Set<PropertySourceLoader> propertySourceLoaders = new HashSet<>();
|
Set<PropertySourceLoader> propertySourceLoaders = new HashSet<>();
|
||||||
propertySourceLoaders.add(new PropertiesPropertySourceLoader());
|
propertySourceLoaders.add(new PropertiesPropertySourceLoader());
|
||||||
|
|
@ -68,6 +75,15 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
PROPERTY_SOURCE_LOADERS = Collections.unmodifiableSet(propertySourceLoaders);
|
PROPERTY_SOURCE_LOADERS = Collections.unmodifiableSet(propertySourceLoaders);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public DevToolsHomePropertiesPostProcessor() {
|
||||||
|
this(System.getenv(), System.getProperties());
|
||||||
|
}
|
||||||
|
|
||||||
|
DevToolsHomePropertiesPostProcessor(Map<String, String> environmentVariables, Properties systemProperties) {
|
||||||
|
this.environmentVariables = environmentVariables;
|
||||||
|
this.systemProperties = systemProperties;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
|
||||||
if (DevToolsEnablementDeducer.shouldEnable(Thread.currentThread())) {
|
if (DevToolsEnablementDeducer.shouldEnable(Thread.currentThread())) {
|
||||||
|
|
@ -93,7 +109,7 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
|
|
||||||
private void addPropertySource(List<PropertySource<?>> propertySources, String fileName,
|
private void addPropertySource(List<PropertySource<?>> propertySources, String fileName,
|
||||||
Function<File, String> propertySourceNamer) {
|
Function<File, String> propertySourceNamer) {
|
||||||
File home = getProjectRootFolder();
|
File home = getHomeDirectory();
|
||||||
File file = (home != null) ? new File(home, fileName) : null;
|
File file = (home != null) ? new File(home, fileName) : null;
|
||||||
FileSystemResource resource = (file != null) ? new FileSystemResource(file) : null;
|
FileSystemResource resource = (file != null) ? new FileSystemResource(file) : null;
|
||||||
if (resource != null && resource.exists() && resource.isFile()) {
|
if (resource != null && resource.exists() && resource.isFile()) {
|
||||||
|
|
@ -121,21 +137,19 @@ public class DevToolsHomePropertiesPostProcessor implements EnvironmentPostProce
|
||||||
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
|
.anyMatch((fileExtension) -> StringUtils.endsWithIgnoreCase(name, fileExtension));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected File getProjectRootFolder() {
|
protected File getHomeDirectory() {
|
||||||
String rootFolder = System.getenv("PROJECT_ROOT_FOLDER");
|
return getHomeDirectory(() -> this.environmentVariables.get("SPRING_DEVTOOLS_HOME"),
|
||||||
if (rootFolder == null) {
|
() -> this.systemProperties.getProperty("spring.devtools.home"),
|
||||||
rootFolder = System.getProperty("PROJECT_ROOT_FOLDER");
|
() -> this.systemProperties.getProperty("user.home"));
|
||||||
}
|
|
||||||
if (StringUtils.hasLength(rootFolder)) {
|
|
||||||
return new File(rootFolder);
|
|
||||||
}
|
|
||||||
return getHomeDirectory();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected File getHomeDirectory() {
|
@SafeVarargs
|
||||||
String home = System.getProperty("user.home");
|
private final File getHomeDirectory(Supplier<String>... pathSuppliers) {
|
||||||
if (StringUtils.hasLength(home)) {
|
for (Supplier<String> pathSupplier : pathSuppliers) {
|
||||||
return new File(home);
|
String path = pathSupplier.get();
|
||||||
|
if (StringUtils.hasText(path)) {
|
||||||
|
return new File(path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.file.Files;
|
import java.nio.file.Files;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
|
||||||
import org.junit.jupiter.api.BeforeEach;
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
|
@ -47,12 +49,12 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
|
|
||||||
private File home;
|
private File home;
|
||||||
|
|
||||||
private File rootDir;
|
private File customHome;
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup(@TempDir File tempDir, @TempDir File rootDir) {
|
void setup(@TempDir File tempDir) {
|
||||||
this.home = tempDir;
|
this.home = new File(tempDir, "default-home");
|
||||||
this.rootDir = rootDir;
|
this.customHome = new File(tempDir, "custom-home");
|
||||||
this.configDir = this.home + "/.config/spring-boot/";
|
this.configDir = this.home + "/.config/spring-boot/";
|
||||||
new File(this.configDir).mkdirs();
|
new File(this.configDir).mkdirs();
|
||||||
}
|
}
|
||||||
|
|
@ -67,17 +69,25 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void loadsRootFolderProperties() throws Exception {
|
void loadsPropertiesFromCustomHomeDirectorySetUsingSystemProperty() throws Exception {
|
||||||
System.setProperty("PROJECT_ROOT_FOLDER", this.rootDir.getAbsolutePath());
|
|
||||||
Properties properties = new Properties();
|
Properties properties = new Properties();
|
||||||
properties.put("uvw", "xyz");
|
properties.put("uvw", "xyz");
|
||||||
OutputStream out = new FileOutputStream(
|
writeFile(properties, this.customHome, ".config/spring-boot/spring-boot-devtools.properties");
|
||||||
new File(this.rootDir, ".config/spring-boot/spring-boot-devtools.properties"));
|
Properties systemProperties = new Properties();
|
||||||
properties.store(out, null);
|
systemProperties.setProperty("spring.devtools.home", this.customHome.getAbsolutePath());
|
||||||
out.close();
|
ConfigurableEnvironment environment = getPostProcessedEnvironment(systemProperties);
|
||||||
ConfigurableEnvironment environment = new MockEnvironment();
|
assertThat(environment.getProperty("uvw")).isEqualTo("xyz");
|
||||||
MockDevToolHomePropertiesPostProcessor postProcessor = new MockDevToolHomePropertiesPostProcessor();
|
}
|
||||||
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, null));
|
|
||||||
|
@Test
|
||||||
|
void loadsPropertiesFromCustomHomeDirectorySetUsingEnvironmentVariable() throws Exception {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.put("uvw", "xyz");
|
||||||
|
writeFile(properties, this.customHome, ".config/spring-boot/spring-boot-devtools.properties");
|
||||||
|
Properties systemProperties = new Properties();
|
||||||
|
systemProperties.setProperty("spring.devtools.home", this.customHome.getAbsolutePath());
|
||||||
|
ConfigurableEnvironment environment = getPostProcessedEnvironment(
|
||||||
|
Collections.singletonMap("SPRING_DEVTOOLS_HOME", this.customHome.getAbsolutePath()));
|
||||||
assertThat(environment.getProperty("uvw")).isEqualTo("xyz");
|
assertThat(environment.getProperty("uvw")).isEqualTo("xyz");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,15 +179,39 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
assertThat(environment.getProperty("abc")).isNull();
|
assertThat(environment.getProperty("abc")).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void writeFile(Properties properties, String s) throws IOException {
|
private void writeFile(Properties properties, String path) throws IOException {
|
||||||
OutputStream out = new FileOutputStream(new File(this.home, s));
|
writeFile(properties, this.home, path);
|
||||||
properties.store(out, null);
|
}
|
||||||
out.close();
|
|
||||||
|
private void writeFile(Properties properties, File home, String path) throws IOException {
|
||||||
|
File file = new File(home, path);
|
||||||
|
file.getParentFile().mkdirs();
|
||||||
|
try (OutputStream out = new FileOutputStream(file)) {
|
||||||
|
properties.store(out, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ConfigurableEnvironment getPostProcessedEnvironment() throws Exception {
|
private ConfigurableEnvironment getPostProcessedEnvironment() throws Exception {
|
||||||
|
return getPostProcessedEnvironment(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurableEnvironment getPostProcessedEnvironment(Properties systemProperties) throws Exception {
|
||||||
|
return getPostProcessedEnvironment(null, systemProperties);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurableEnvironment getPostProcessedEnvironment(Map<String, String> env) throws Exception {
|
||||||
|
return getPostProcessedEnvironment(env, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConfigurableEnvironment getPostProcessedEnvironment(Map<String, String> env, Properties systemProperties)
|
||||||
|
throws Exception {
|
||||||
|
if (systemProperties == null) {
|
||||||
|
systemProperties = new Properties();
|
||||||
|
systemProperties.setProperty("user.home", this.home.getAbsolutePath());
|
||||||
|
}
|
||||||
ConfigurableEnvironment environment = new MockEnvironment();
|
ConfigurableEnvironment environment = new MockEnvironment();
|
||||||
MockDevToolHomePropertiesPostProcessor postProcessor = new MockDevToolHomePropertiesPostProcessor();
|
DevToolsHomePropertiesPostProcessor postProcessor = new DevToolsHomePropertiesPostProcessor(
|
||||||
|
(env != null) ? env : Collections.emptyMap(), systemProperties);
|
||||||
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, null));
|
runPostProcessor(() -> postProcessor.postProcessEnvironment(environment, null));
|
||||||
return environment;
|
return environment;
|
||||||
}
|
}
|
||||||
|
|
@ -188,13 +222,4 @@ class DevToolsHomePropertiesPostProcessorTests {
|
||||||
thread.join();
|
thread.join();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class MockDevToolHomePropertiesPostProcessor extends DevToolsHomePropertiesPostProcessor {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected File getHomeDirectory() {
|
|
||||||
return DevToolsHomePropertiesPostProcessorTests.this.home;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -285,6 +285,9 @@ For example, to configure restart to always use a <<using#using.devtools.restart
|
||||||
trigger-file: ".reloadtrigger"
|
trigger-file: ".reloadtrigger"
|
||||||
----
|
----
|
||||||
|
|
||||||
|
By default, `$HOME` is the user's home directory.
|
||||||
|
To customize this location, set the `SPRING_DEVTOOLS_HOME` environment variable or the `spring.devtools.home` system property.
|
||||||
|
|
||||||
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.
|
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.
|
||||||
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.
|
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.
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue