FeedReaderCommandRunner.java
package net.sasasin.sreader.runner;
import java.util.Arrays;
import java.util.List;
import net.sasasin.sreader.cli.SreaderCliExecutor;
import net.sasasin.sreader.config.FeedReaderProperties;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class FeedReaderCommandRunner implements CommandLineRunner {
private static final List<String> SPRING_PROP_PREFIXES =
List.of("--spring.", "--sreader.", "--server.", "--management.");
private final FeedReaderProperties properties;
private final ConfigurableApplicationContext applicationContext;
private final SreaderCliExecutor cliExecutor;
public FeedReaderCommandRunner(
FeedReaderProperties properties,
ConfigurableApplicationContext applicationContext,
SreaderCliExecutor cliExecutor) {
this.properties = properties;
this.applicationContext = applicationContext;
this.cliExecutor = cliExecutor;
}
@Override
public void run(String... args) throws Exception {
String[] filtered = filterSpringBootOptions(args);
if (filtered.length > 0) {
exitApplication(cliExecutor.execute(filtered));
} else if (properties.job().runOnce()) {
exitApplication(cliExecutor.execute("run-once"));
}
// otherwise fall through: application keeps running as daemon
// (scheduler will trigger periodic jobs per sreader.scheduler.* config)
}
/**
* Remove Spring Boot / sreader property arguments before passing to picocli. Supports usage like:
* java -jar app.jar --sreader.scheduler.enabled=false feeds import --input feeds.toml
*/
private String[] filterSpringBootOptions(String[] args) {
return Arrays.stream(args)
.filter(a -> SPRING_PROP_PREFIXES.stream().noneMatch(a::startsWith))
.toArray(String[]::new);
}
private void exitApplication(int exitCode) {
int resolvedExitCode = SpringApplication.exit(applicationContext, () -> exitCode);
if (resolvedExitCode != 0) {
exitProcess(Math.max(exitCode, resolvedExitCode));
}
}
/** Invokes the JVM exit operation after Spring has closed the application context. */
void exitProcess(int exitCode) {
System.exit(exitCode);
}
}