Application configuration directory not required to be writable
All checks were successful
CI / build (push) Successful in 49s

This commit is contained in:
2025-06-10 16:11:35 +08:00
parent 3b55366347
commit c5e4690856
4 changed files with 15 additions and 14 deletions

View File

@@ -4,12 +4,10 @@ on:
branches: [ master ] branches: [ master ]
jobs: jobs:
build: build:
runs-on: hostinger runs-on: woryzen
steps: steps:
- name: Checkout sources - name: Checkout sources
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
- name: Execute Gradle build - name: Execute Gradle build
env: env:
PUBLISHER_TOKEN: ${{ secrets.PUBLISHER_TOKEN }} PUBLISHER_TOKEN: ${{ secrets.PUBLISHER_TOKEN }}

View File

@@ -3,6 +3,6 @@ org.gradle.parallel=true
org.gradle.caching=true org.gradle.caching=true
gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven gitea.maven.url = https://gitea.woggioni.net/api/packages/woggioni/maven
jwo.version = 2025.04.19 jwo.version = 2025.06.10
lys.version = 2025.04.16 lys.version = 2025.06.03
guice.version = 5.0.1 guice.version = 5.0.1

View File

@@ -35,7 +35,7 @@ public class Application {
return new Builder().name(name); return new Builder().name(name);
} }
private static boolean validateWritableDirectory(Path candidate) { private static boolean validateDirectory(Path candidate, boolean writable) {
try { try {
if (!Files.exists(candidate)) { if (!Files.exists(candidate)) {
Files.createDirectories(candidate); Files.createDirectories(candidate);
@@ -44,7 +44,7 @@ public class Application {
} else if (!Files.isDirectory(candidate)) { } else if (!Files.isDirectory(candidate)) {
log.trace("Directory '{}' discarded because it is not a directory", candidate); log.trace("Directory '{}' discarded because it is not a directory", candidate);
return false; return false;
} else if (!Files.isWritable(candidate)) { } else if (writable && !Files.isWritable(candidate)) {
log.trace("Directory '{}' discarded because it is not writable", candidate); log.trace("Directory '{}' discarded because it is not writable", candidate);
return false; return false;
} else { } else {
@@ -61,9 +61,9 @@ public class Application {
} }
@SneakyThrows @SneakyThrows
private Path selectWritableDirectory(Stream<Path> candidates, String successMessage, String errorMessage) { private Path selectDirectory(Stream<Path> candidates, boolean writable, String successMessage, String errorMessage) {
return candidates return candidates
.filter(Application::validateWritableDirectory) .filter(p -> validateDirectory(p, writable))
.peek(p -> log.debug(successMessage, p)) .peek(p -> log.debug(successMessage, p))
.findFirst() .findFirst()
.orElseThrow((Sup<Throwable>) () -> new FileNotFoundException(errorMessage)); .orElseThrow((Sup<Throwable>) () -> new FileNotFoundException(errorMessage));
@@ -99,7 +99,8 @@ public class Application {
Optional.ofNullable(System.getProperty("user.home")) Optional.ofNullable(System.getProperty("user.home"))
.map(prefix -> Paths.get(prefix, "." + name, "cache"))); .map(prefix -> Paths.get(prefix, "." + name, "cache")));
} }
return selectWritableDirectory(streamCat(commonCandidates, osSpecificCandidates), return selectDirectory(streamCat(commonCandidates, osSpecificCandidates),
true,
"Using cache directory '{}'", "Using cache directory '{}'",
"Unable to find a usable cache directory"); "Unable to find a usable cache directory");
} }
@@ -134,13 +135,14 @@ public class Application {
Optional.ofNullable(System.getProperty("user.home")) Optional.ofNullable(System.getProperty("user.home"))
.map(prefix -> Paths.get(prefix, "." + name))); .map(prefix -> Paths.get(prefix, "." + name)));
} }
return selectWritableDirectory(streamCat(commonCandidates, osSpecificCandidates), return selectDirectory(streamCat(commonCandidates, osSpecificCandidates),
true,
"Using data directory '{}'", "Using data directory '{}'",
"Unable to find a usable data directory"); "Unable to find a usable data directory");
} }
@SneakyThrows @SneakyThrows
public Path computeConfigurationDirectory() { public Path computeConfigurationDirectory(boolean writable) {
Stream<Path> commonCandidates = optional2Stream( Stream<Path> commonCandidates = optional2Stream(
Optional.ofNullable(configurationDirectoryPropertyKey).map(System::getProperty).map(Paths::get), Optional.ofNullable(configurationDirectoryPropertyKey).map(System::getProperty).map(Paths::get),
Optional.ofNullable(configurationDirectoryEnvVar).map(System::getenv).map(Paths::get) Optional.ofNullable(configurationDirectoryEnvVar).map(System::getenv).map(Paths::get)
@@ -169,7 +171,8 @@ public class Application {
Optional.ofNullable(System.getProperty("user.home") Optional.ofNullable(System.getProperty("user.home")
).map(prefix -> Paths.get(prefix, "." + name, "config"))); ).map(prefix -> Paths.get(prefix, "." + name, "config")));
} }
return selectWritableDirectory(streamCat(commonCandidates, osSpecificCandidates), return selectDirectory(streamCat(commonCandidates, osSpecificCandidates),
writable,
"Using configuration directory '{}'", "Using configuration directory '{}'",
"Unable to find a usable configuration directory"); "Unable to find a usable configuration directory");
} }

View File

@@ -14,7 +14,7 @@ public class ApplicationTest {
.dataDirectoryEnvVar("APP_DATA_DIR") .dataDirectoryEnvVar("APP_DATA_DIR")
.configurationDirectoryEnvVar("APP_CONF_DIR") .configurationDirectoryEnvVar("APP_CONF_DIR")
.build(); .build();
final var confDir = app.computeConfigurationDirectory(); final var confDir = app.computeConfigurationDirectory(true);
final var cacheDir = app.computeCacheDirectory(); final var cacheDir = app.computeCacheDirectory();
final var dataDir = app.computeDataDirectory(); final var dataDir = app.computeDataDirectory();
} }