spring-boot icon indicating copy to clipboard operation
spring-boot copied to clipboard

A functional command line runner

Open xenoterracide opened this issue 4 years ago • 3 comments

So in order to do a command line runner with an exit code you have to do mutable state (at least from what I can find documented), here's picocli's example

import picocli.CommandLine;
import picocli.CommandLine.IFactory;

import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.stereotype.Component;

@Component
public class MyApplicationRunner implements CommandLineRunner, ExitCodeGenerator {

	private final MyCommand myCommand;

	private final IFactory factory; // auto-configured to inject PicocliSpringFactory

	private int exitCode;

	public MyApplicationRunner(MyCommand myCommand, IFactory factory) {
		this.myCommand = myCommand;
		this.factory = factory;
	}

	@Override
	public void run(String... args) throws Exception {
		exitCode = new CommandLine(myCommand, factory).execute(args);
	}

	@Override
	public int getExitCode() {
		return exitCode;
	}
}

and from what little is in the reference documentation this s true, I think we need an interface that can work without mutability.

interface ExitingCommandLineRunner {

   int run( String... args );
}

xenoterracide avatar Apr 09 '21 00:04 xenoterracide

The exit code logic could certainly do with a refresh. We have another issue (#25100) related to the SpringApplication.exit method.

One trick that might work in the meantime is to put ExitCodeGenerator on an exception:

@Component
public class MyApplicationRunner implements CommandLineRunner {

	private final MyCommand myCommand;

	private final IFactory factory; // auto-configured to inject PicocliSpringFactory

	public MyApplicationRunner(MyCommand myCommand, IFactory factory) {
		this.myCommand = myCommand;
		this.factory = factory;
	}

	@Override
	public void run(String... args) throws Exception {
		int exitCode = new CommandLine(myCommand, factory).execute(args);
		if (exitCode != 0) {
			throw new MyExitException(exitCode);
		}
	}

	static class ExitException implements ExitCodeGenerator {

		private final int code;

		ExitException(int code) {
			this.code = code;
		}

		@Override
		public int getExitCode() {
			return this.code;
		}

	}

}

philwebb avatar Apr 09 '21 00:04 philwebb

Hello, i would like to solve this issue

raqueru avatar Dec 02 '21 18:12 raqueru

Should this interface be implemented only by classes that use exit code or in general? I can't seem to find any example of run codes that use exit code in general

raqueru avatar Dec 14 '21 15:12 raqueru