Picocliï¼Spring Boot ã§ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ãä½æãã¦ã¿ã
æ¦è¦
è¨äºä¸è¦§ã¯ãã¡ãã§ãã
Twitter ãè¦ã¦ããã¨ãã picocli ã¨ããã©ã¤ãã©ãªã® 4.0 GA release ã®ãã¤ã¼ããè¦ããã¾ãããpicocli ã®ãã¨ãç¥ããªãã£ãã®ã§èª¿ã¹ã¦ã¿ãã¨ããã
- Java 㧠command line application ãä½æããããã® frameworkãèãããããã®ã¯ã»ã¨ãã©å®è£ ããã¦ããã®ã§ã¯ãªãã ããããã¨ãããããæ©è½ãå å®ãã¦ãããããã¥ã¢ã«ãåãããããã
- picocli-spring-boot-starter ãæä¾ããã¦ããã
- bash ã zsh éå®ã ããã³ãã³ãã©ã¤ã³ããå®è¡ããæã« TAB ã§èªåè£å®ãå¹ãã³ãã³ããä½æã§ããã
- GraalVM ã«å¯¾å¿ãã¦ããããããGraalVM ãå ¨ç¶ç解ãã¦ããªãã®ã§èªåã§ã¯ã©ã対å¿ããã¦ããã®ãå ¨ãåããã¾ããã§ãããããã
調ã¹ããã¨ãã¡ã¢ãã¦æ®ãããµã³ãã«ãä½æãã¦ã¿ã¾ããä½æãããµã³ãã«ã¯ä»¥ä¸ã® URL ã®å ´æã«ç½®ãã¦ããã¾ãã
https://github.com/ksby/ksbysample-boot-miscellaneous/tree/master/picocli-boot-cmdapp
åç §ãããµã¤ãã»æ¸ç±
picocli - a mighty tiny command line interface
https://picocli.info/Quick Guide
https://picocli.info/quick-guide.htmlremkop/picocli
https://github.com/remkop/picoclipicocli/picocli-spring-boot-starter/
https://github.com/remkop/picocli/tree/master/picocli-spring-boot-starterAutocomplete for Java Command Line Applications
https://picocli.info/autocomplete.htmlCreate a Java Command Line Program with Picocli
https://www.baeldung.com/java-picocli-create-command-line-programSpring Boot Exit Codes
https://www.baeldung.com/spring-boot-exit-codesIncluding subprojects using a wildcard in a Gradle settings file
https://stackoverflow.com/questions/2297032/including-subprojects-using-a-wildcard-in-a-gradle-settings-file
ç®æ¬¡
- Spring Boot ãã¼ã¹ã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ã®ãµã³ãã«ãä½æããï¼Subcommand ãªãï¼
- Spring Boot ãã¼ã¹ã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ã®ãµã³ãã«ãä½æããï¼Subcommand ããï¼
- --versionï¼-Vï¼ãªãã·ã§ã³æå®æã« build.gradle ã«è¨è¿°ãã build.version ã表示ãã
- TAB ãã¼æ¼ä¸æã« subcommand, option ã®åè£ã®è¡¨ç¤ºãèªåè£å®ãè¡ãããããã«ãã
æé
Spring Boot ãã¼ã¹ã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ã®ãµã³ãã«ãä½æããï¼Subcommand ãªãï¼
Subcommand ãªã㨠Subcommand ããã®ï¼ã¤ã®ãµã³ãã«ã Gradle Multi-project ã®ä¸ã«ä½æãã¾ãã
D:\project-springboot\ksbysample-boot-miscellaneous
ã®ä¸ã« picocli-boot-cmdapp ãã£ã¬ã¯ããªãä½æããã- å¥ã®ããã¸ã§ã¯ããã Gradle Wrapper ã®ãã¡ã¤ã«ãã³ãã¼ããï¼ã³ãã¼ããã®ã¯ 5.4.1ï¼ã
- Gradle ãææ°ãã¼ã¸ã§ã³ï¼5.5.1ï¼ã«ããã
gradlew init
ãå®è¡ããã- settings.gradle ã以ä¸ã®å 容ã«å¤æ´ããï¼Including subprojects using a wildcard in a Gradle settings file åç §ï¼ããã㧠build.gradle ããããµãããã¸ã§ã¯ã㯠include åãè¨è¿°ããªãã¦ãèªåçã« Multi-project ã«èªèãããããã«ãªãã
rootProject.name = 'picocli-boot-cmdapp' rootDir.eachFileRecurse { f -> if ( f.name == "build.gradle" ) { String relativePath = f.parentFile.absolutePath - rootDir.absolutePath String projectName = relativePath.replaceAll("[\\\\\\/]", ":") include projectName } }
Multi-project ã®ãã¼ã¹ãåºæ¥ã¾ããã次㫠Spring Boot ãã¼ã¹ã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ï¼Subcommand ãªãï¼ã® Project ãä½æãã¾ãã以ä¸ã®ä»æ§ã®ã³ãã³ããä½æãã¾ãã
filetools --create <ãã¡ã¤ã«> <ãã¡ã¤ã«> ...
ï¼--create 㯠-c ãå¯ï¼ ã§æå®ããããã¡ã¤ã«åã®ç©ºãã¡ã¤ã«ãä½æãããfiletools --delete <ãã¡ã¤ã«> <ãã¡ã¤ã«> ...
ï¼--delete 㯠-d ãå¯ï¼ ã§æå®ããããã¡ã¤ã«ãåé¤ããã--create
ã¨--delete
ã®ãªãã·ã§ã³ã¯ããããä¸æ¹ãå¿ é ãã©ã¡ããæå®ããªãããããã¯ã©ã¡ããæå®ããå ´åã«ã¯ã¨ã©ã¼ã«ãªãã
ã¾ã D:\project-springboot\ksbysample-boot-miscellaneous\picocli-boot-cmdapp
ã®ä¸ã« Spring Initializr 㧠nosubcmd-cmdapp ããã¸ã§ã¯ããä½æããå¾ãbuild.gradle ã以ä¸ã®ããã«å¤æ´ãã¾ãã
buildscript { ext { group "ksby.ksbysample-boot-miscellaneous.picocli-boot-cmdapp" version "1.0.0-RELEASE" } repositories { mavenCentral() maven { url "https://repo.spring.io/release/" } maven { url "https://plugins.gradle.org/m2/" } } } plugins { id 'org.springframework.boot' version '2.1.6.RELEASE' id "io.spring.dependency-management" version "1.0.8.RELEASE" id 'java' id 'idea' } sourceCompatibility = JavaVersion.VERSION_11 targetCompatibility = JavaVersion.VERSION_11 idea { module { inheritOutputDirs = false outputDir = file("$buildDir/classes/main/") } } repositories { mavenCentral() } dependencyManagement { imports { mavenBom(org.springframework.boot.gradle.plugin.SpringBootPlugin.BOM_COORDINATES) } } dependencies { def picocliVersion = "4.0.0" implementation("org.springframework.boot:spring-boot-starter") testImplementation("org.springframework.boot:spring-boot-starter-test") // picocli implementation("info.picocli:picocli-spring-boot-starter:${picocliVersion}") }
- dependencies block ã« Picocli ã® Spring Boot Starter ã§ãã picocli-spring-boot-starter ã追å ãã¾ãã
src/main/java/ksbysample/cmdapp/nosubcmd ã®ä¸ã« FileToolsCommand.java ãæ°è¦ä½æãã¦ã以ä¸ã®å 容ãè¨è¿°ãã¾ãã
package ksbysample.cmdapp.nosubcmd; import org.springframework.stereotype.Component; import picocli.CommandLine.*; import java.io.File; import java.io.IOException; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileSystemException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.concurrent.Callable; @Component @Command(name = "filetools", mixinStandardHelpOptions = true, version = "1.0.0", description = "create/delete file(s) command") public class FileToolsCommand implements Callable<Integer>, IExitCodeExceptionMapper { // --create ãªãã·ã§ã³ã¨ --delete ãªãã·ã§ã³ã¯ããããä¸æ¹ããæå®ã§ããªãããã«ãã @ArgGroup(exclusive = true, multiplicity = "1") private Exclusive exclusive; static class Exclusive { @Option(names = {"-c", "--create"}, description = "create file(s)") private boolean isCreate; @Option(names = {"-d", "--delete"}, description = "delete file(s)") private boolean isDelete; } @Parameters(paramLabel = "ãã¡ã¤ã«", description = "ä½æãããã¯åé¤ãããã¡ã¤ã«") private File[] files; @Override public Integer call() { Arrays.asList(this.files).forEach(f -> { try { if (exclusive.isCreate) { Files.createFile(Paths.get(f.getName())); System.out.println(f.getName() + " is created."); } else if (exclusive.isDelete) { Files.deleteIfExists(Paths.get(f.getName())); System.out.println(f.getName() + " is deleted."); } } catch (IOException e) { throw new RuntimeException(e); } }); return ExitCode.OK; } @Override public int getExitCode(Throwable exception) { Throwable cause = exception.getCause(); if (cause instanceof FileAlreadyExistsException) { // æ¢ã«åå¨ãããã¡ã¤ã«ãä½æãããã¨ãã¦ãã return 12; } else if (cause instanceof FileSystemException) { // åé¤ãããã¨ãããã¡ã¤ã«ãå¥ã®ããã»ã¹ã§ãªã¼ãã³ããã¦ããç return 13; } return 11; } }
src/main/java/ksbysample/cmdapp/nosubcmd/Application.java ã以ä¸ã®ããã«å¤æ´ãã¾ãã
package ksbysample.cmdapp.nosubcmd; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import picocli.CommandLine; import picocli.CommandLine.IFactory; @SpringBootApplication public class Application implements CommandLineRunner, ExitCodeGenerator { private int exitCode; private final FileToolsCommand fileToolsCommand; private final IFactory factory; public Application(FileToolsCommand fileToolsCommand, IFactory factory) { this.fileToolsCommand = fileToolsCommand; this.factory = factory; } public static void main(String[] args) { System.exit(SpringApplication.exit(SpringApplication.run(Application.class, args))); } @Override public void run(String... args) { exitCode = new CommandLine(fileToolsCommand, factory) .setExitCodeExceptionMapper(fileToolsCommand) .execute(args); } @Override public int getExitCode() { return exitCode; } }
gradle ã® build ã¿ã¹ã¯ãå®è¡ã㦠build/libs ã®ä¸ã« nosubcmd-cmdapp-1.0.0-RELEASE.jar ãçæãã¾ãã
Git for Windows ã® bash ãèµ·åãã¦ãã D:\project-springboot\ksbysample-boot-miscellaneous\picocli-boot-cmdapp\nosubcmd-cmdapp\build\libs\
ã®ä¸ã«ç§»åããalias filetools='java -jar nosubcmd-cmdapp-1.0.0-RELEASE.jar'
ã³ãã³ããå®è¡ã㦠filetools
ã ãã§ã³ãã³ããå®è¡ã§ããããã«ãã¾ãã
filetools
ã³ãã³ããå®è¡ãã¦ã¿ãã¨ã
Spring Boot ã®ãã´ã¨ INFO ãã°ãéªéã§ããããããä»åã¯è¡¨ç¤ºãããªãããã«ãã¾ãã
src/main/resources/application.properties ã«ä»¥ä¸ã®å 容ãè¨è¼ãã¾ãã
spring.main.banner-mode=off logging.level.root=OFF
build ãç´ãã¦ãã filetools
ã³ãã³ããå®è¡ãã㨠-c, -d ã®ã©ã¡ãã®ãªãã·ã§ã³ãæå®ãã¦ããªãã¨ããã¨ã©ã¼ã¡ãã»ã¼ã¸ï¼Error: Missing required argument (specify one of these): ([-c] | [-d])
ï¼ã¨ãã«ãã表示ããã¾ãããããã ãã®è¨è¿°ãªã®ã«ãã«ãã¯è¦ããããããªãã·ã§ã³ã®ã¨ããã«è²ãä»ãã¦ããã®ãããã§ããã
-c, -d ã®ãªãã·ã§ã³ãã©ã¡ããæå®ãã㨠Error: --create, --delete are mutually exclusive (specify only one)
ã¨ããã¨ã©ã¼ã¡ãã»ã¼ã¸ã表示ããã¾ãã
filetools -h
ã³ãã³ããå®è¡ããã¨ãã«ãã ãã表示ãããfiletools -V
ã³ãã³ããå®è¡ããã¨ãã¼ã¸ã§ã³çªå·ã ãã表示ããã¾ãã
ãã¡ã¤ã«ã®ä½æãåé¤ã試ãã¦ã¿ã¾ãããã£ã¬ã¯ããªå ã« jar 以å¤ã®ãã¡ã¤ã«ããªãç¶æ ã§ã
filetools -c 1.txt 2.txt 3.txt
ã³ãã³ããå®è¡ããã¨ã
ãã£ã¬ã¯ããªå ã«ãã¡ã¤ã«ãä½æããã¾ãã
filetools -d 1.txt 2.txt 3.txt
ã³ãã³ããå®è¡ããã¨ã
ãã¡ã¤ã«ãåé¤ããã¾ãã
filetools -c a.txt a.txt
ã³ãã³ããå®è¡ãã¦åããã¡ã¤ã«ãï¼åº¦ä½æãããã¨ããã¨ãã³ãã³ãã®æ»ãå¤ã 0 ã§ã¯ãªã 12 ã«ãªãã¾ãã
Spring Boot ãã¼ã¹ã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ã®ãµã³ãã«ãä½æããï¼Subcommand ããï¼
ä»åº¦ã¯ Subcommand ããã®ã³ãã³ãã©ã¤ã³ã¢ããªã±ã¼ã·ã§ã³ãä½æãã¦ã¿ã¾ããGit ã³ãã³ãã§ã® git commit ...
ã git branch ...
ã®ããã« commit, branch ã Subcommand ã«ãããã¾ãã
以ä¸ã®ä»æ§ã®ã³ãã³ããä½æãã¾ãã
cal add æ°å¤ æ°å¤ ...
ã§æå®ãããæ°å¤ãå ¨ã¦å ç®ããçµæã表示ããã--avg
ï¼'-a' ã§ãå¯ï¼ãªãã·ã§ã³ãä»ããã¨æ°å¤ã®åæ°ã§å²ã£ãå¹³åå¤ã表示ãããcal multi æ°å¤ æ°å¤ ...
ã§æå®ãããæ°å¤ãå ¨ã¦ä¹ç®ããçµæã表示ããã--compare æ°å¤
ãªãã·ã§ã³ãä»ããã¨è¨ç®çµæã¨æ°å¤ãæ¯è¼ãã¦ãè¨ç®çµæ < æ°å¤ãªã -1ãè¨ç®çµæ = æ°å¤ãªã 0ãè¨ç®çµæ > æ°å¤ãªã 1 ãè¿ãã
ã¾ã D:\project-springboot\ksbysample-boot-miscellaneous\picocli-boot-cmdapp
ã®ä¸ã« Spring Initializr 㧠subcmd-cmdapp ããã¸ã§ã¯ããä½æããå¾ãnosubcmd-cmdapp ããã¸ã§ã¯ãã® build.gradle ãã³ãã¼ãã¾ãã
src/main/java/ksbysample/cmdapp/subcmd ã®ä¸ã« CalCommand.java ãæ°è¦ä½æãã¦ã以ä¸ã®å 容ãè¨è¼ãã¾ãã
package ksbysample.cmdapp.subcmd; import org.springframework.stereotype.Component; import picocli.CommandLine.*; import java.math.BigDecimal; import java.util.Arrays; import java.util.Optional; import java.util.concurrent.Callable; @Component @Command(name = "cal", mixinStandardHelpOptions = true, versionProvider = CalCommand.class, description = "渡ãããæ°å¤ã®å ç®ã»ä¹ç®ãè¡ããã¼ã«", subcommands = { CalCommand.AddCommand.class, CalCommand.MultiCommand.class }) public class CalCommand implements Callable<Integer>, IExitCodeExceptionMapper, IVersionProvider { @Override public Integer call() { return ExitCode.OK; } @Override public int getExitCode(Throwable exception) { Throwable cause = exception.getCause(); if (cause instanceof NumberFormatException) { // æ°å¤ãã©ã¡ã¼ã¿ã«æ°å¤ä»¥å¤ã®æåãæå®ããã return 12; } return 11; } @Override public String[] getVersion() { return new String[]{"1.0.0"}; } @Component @Command(name = "add", mixinStandardHelpOptions = true, versionProvider = CalCommand.class, description = "渡ãããæ°å¤ãå ç®ãã") static class AddCommand implements Callable<Integer> { @Option(names = {"-a", "--avg"}, description = "å¹³åå¤ãç®åºãã") private boolean optAvg; @Parameters(paramLabel = "æ°å¤", arity = "1..*", description = "å ç®ããæ°å¤") private BigDecimal[] nums; @Override public Integer call() { BigDecimal sum = Arrays.asList(nums).stream() .reduce(new BigDecimal("0"), (a, v) -> a.add(v)); Optional<BigDecimal> avg = optAvg ? Optional.of(sum.divide(BigDecimal.valueOf(nums.length))) : Optional.empty(); System.out.println(avg.orElse(sum)); return ExitCode.OK; } } @Component @Command(name = "multi", mixinStandardHelpOptions = true, versionProvider = CalCommand.class, description = "渡ãããæ°å¤ãä¹ç®ãã") static class MultiCommand implements Callable<Integer> { @Parameters(paramLabel = "æ°å¤", arity = "1..*", description = "ä¹ç®ããæ°å¤") private BigDecimal[] nums; @Option(names = {"-c", "--compare"}, description = "è¨ç®çµæã¨æ¯è¼ãã¦ãè¨ç®çµæ < æ°å¤ãªã -1ãè¨ç®çµæ = æ°å¤ãªã 0ãè¨ç®çµæ > æ°å¤ãªã 1 ãè¿ã") private BigDecimal compareNum; @Override public Integer call() { BigDecimal result = Arrays.asList(nums).stream() .reduce(new BigDecimal("1"), (a, v) -> a.multiply(v)); Optional<Integer> compareResult = (compareNum == null) ? Optional.empty() : Optional.of(result.compareTo(compareNum)); System.out.println(compareResult.isPresent() ? compareResult.get() : result); return ExitCode.OK; } } }
src/main/java/ksbysample/cmdapp/subcmd/Application.java ã以ä¸ã®ããã«å¤æ´ãã¾ãã
package ksbysample.cmdapp.subcmd; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.ExitCodeGenerator; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import picocli.CommandLine; import picocli.CommandLine.ExitCode; import picocli.CommandLine.IFactory; import picocli.CommandLine.ParameterException; import picocli.CommandLine.ParseResult; @SpringBootApplication public class Application implements CommandLineRunner, ExitCodeGenerator { private int exitCode; private final CalCommand calCommand; private final IFactory factory; public Application(CalCommand calCommand , IFactory factory) { this.calCommand = calCommand; this.factory = factory; } public static void main(String[] args) { System.exit(SpringApplication.exit(SpringApplication.run(Application.class, args))); } @Override public void run(String... args) { CommandLine commandLine = new CommandLine(calCommand, factory); // subcommand ãæå®ããã¦ããªãå ´åã«ã¯ã¨ã©ã¼ã¡ãã»ã¼ã¸ã¨ usage ã表示ãã try { ParseResult parsed = commandLine.parseArgs(args); if (parsed.subcommand() == null && !parsed.isUsageHelpRequested() && !parsed.isVersionHelpRequested()) { System.err.println("Error: at least 1 command and 1 subcommand found."); commandLine.usage(System.out); exitCode = ExitCode.USAGE; return; } } catch (ParameterException ignored) { // CommandLine#parseArgs 㧠ParameterException ã throw ããã¦ã // CommandLine#execute ãå®è¡ããªã㨠subcommand ã® usage ã表示ãããªãã®ã§ // ããã§ã¯ä½ãããªã } exitCode = commandLine .setExitCodeExceptionMapper(calCommand) .execute(args); } @Override public int getExitCode() { return exitCode; } }
src/main/resources/application.properties ã以ä¸ã®ããã«å¤æ´ãã¾ãã
spring.main.banner-mode=off logging.level.root=OFF
bash 㧠D:\project-springboot\ksbysample-boot-miscellaneous\picocli-boot-cmdapp\subcmd-cmdapp\build\libs\
ã®ä¸ã«ç§»åããalias cal='java -jar subcmd-cmdapp-1.0.0-RELEASE.jar'
ã³ãã³ããå®è¡ã㦠cal
ã ãã§ã³ãã³ããå®è¡ã§ããããã«ãã¾ãã
cal
ã³ãã³ãã ããå®è¡ãã㨠Subcommand ãæå®ããã¦ããªãã®ã§ Error: at least 1 command and 1 subcommand found.
ã®ã¨ã©ã¼ã¡ãã»ã¼ã¸ã¨ usage ã表示ããã¾ãã
cal add
ã³ãã³ããå®è¡ããã¨ã
cal multi
ã³ãã³ããå®è¡ããã¨ã
--versionï¼-Vï¼ãªãã·ã§ã³æå®æã« build.gradle ã«è¨è¿°ãã build.version ã表示ãã
build.gradle ã« version ãè¨è¿°ãã¦ããã®ã§ãcal -V
å®è¡æã«ãã®æååãåºåããããã«ãã¦ã¿ã¾ãã
buildscript { ext { group "ksby.ksbysample-boot-miscellaneous.picocli-boot-cmdapp" version "1.0.0-RELEASE" }
ã¾ã build.gradle ã« springBoot { buildInfo() }
ã追å ãã¾ãã
`
idea { module { inheritOutputDirs = false outputDir = file("$buildDir/classes/main/") } } springBoot { buildInfo() } repositories { mavenCentral() }
src/main/java/ksbysample/cmdapp/subcmd/CalCommand.java ã以ä¸ã®ããã«å¤æ´ãã¾ãã
public class CalCommand implements Callable<Integer>, IExitCodeExceptionMapper, IVersionProvider { // picocli.AutoComplete 㧠generate Completion Script ãããæã«å¼æ°ãªãã®ã³ã³ã¹ãã©ã¯ã¿ãå¿ è¦ã«ãªã // ã®ã§ã³ã³ã¹ãã©ã¯ã¿ã¤ã³ã¸ã§ã¯ã·ã§ã³ã¯ä½¿ç¨ããªãã㨠// https://picocli.info/autocomplete.html åç § @Autowired private BuildProperties buildProperties; .......... @Override public String[] getVersion() { return new String[]{buildProperties.getVersion()}; } ..........
private final BuildProperties buildProperties;
ã追å ãã¾ãã- getVersion ã¡ã½ããå
ã§
"1.0.0"
âbuildProperties.getVersion()
ã«å¤æ´ãã¾ãã
build ã㦠jar ãã¡ã¤ã«ãä½æãç´ãã¦ãã cal -V
ã³ãã³ããå®è¡ãã㨠build.gradle ã® version ã«è¨è¿°ããæååã表示ããã¾ãã
TAB ãã¼æ¼ä¸æã« subcommand, option ã®åè£ã®è¡¨ç¤ºãèªåè£å®ãè¡ãããããã«ãã
Autocomplete for Java Command Line Applications ã®ããã¥ã¢ã«ã«å¾ããcal
ã³ãã³ãã® subcommand, option ã®åè£ã®è¡¨ç¤ºãèªåè£å®ãè¡ãããããã«ãã¦ã¿ã¾ãã
subcmd-cmdapp-1.0.0-RELEASE.jar ã zip 解åå¯è½ãªãã¼ã«ï¼ä»å㯠Explzh ã使ç¨ï¼ã§éããå¾ãBOOT-INF/lib ã®ä¸ã«ãã spring-boot-2.1.6.RELEASE.jar 㨠picocli-4.0.0.jar ãåãåºãã¾ãã
java -cp "picocli-4.0.0.jar;subcmd-cmdapp-1.0.0-RELEASE.jar" picocli.AutoComplete -n cal ksbysample.cmdapp.subcmd.CalCommand
ãå®è¡ãã¦ã ClassNotFoundException ãçºçãã¦åä½ããªãã£ãã®ã§ããã
class ãã¡ã¤ã«ã¯ subcmd-cmdapp/build/classes/java/main ã®ä¸ã«çæããã¦ããã®ã§ã
java -cp "picocli-4.0.0.jar;spring-boot-2.1.6.RELEASE.jar;../classes/java/main" picocli.AutoComplete -n cal ksbysample.cmdapp.subcmd.CalCommand
ãå®è¡ãã¾ãã
cal_completion
ã¨ãããã¡ã¤ã«ãçæããã¾ãã
ä½ããã¦ããªãæã«ã¯ bash ä¸ã§ cal
ã¨å
¥åãã¦ãã TAB ãã¼ãï¼åæ¼ãã¨ã¨ãã£ã¬ã¯ããªå
ã®ãã¡ã¤ã«ä¸è¦§ã表示ããã¾ããã
. cal_completion
ã³ãã³ããå®è¡ãã¦ãã cal
ãå
¥åï¼TAB ãã¼ãï¼åæ¼ã㨠subcommand ã®åè£ã表示ããã¾ãã
cal m
ã¨ã ãå
¥åã㦠TABãã¼ãï¼åæ¼ãã¨ã
multi
ã®æååãèªåè£å®ããã¾ãã
cal multi -
ã¨å
¥åãã¦ãã TAB ãã¼ãï¼åæ¼ãã¨æå®å¯è½ãªãªãã·ã§ã³ã表示ããã¾ããã
cal multi --c
ã¨å
¥åãã¦ãã TAB ãã¼ãï¼åæ¼ãã¨
--compare
ã®ãªãã·ã§ã³ãèªåè£å®ããã¾ãã
å±¥æ´
2019/07/20
åççºè¡ã