Skip to content

Instantly share code, notes, and snippets.

@remkop
Last active December 22, 2019 00:47
Show Gist options
  • Save remkop/4d0339d9a7f80fa848735bec745d203a to your computer and use it in GitHub Desktop.
Save remkop/4d0339d9a7f80fa848735bec745d203a to your computer and use it in GitHub Desktop.
Example picocli-based CLI application
/* STEPS FOR CREATING NATIVE IMAGE (MacOS, Linux):
# download this file
mkdir picocli-demo
cd picocli-demo
wget --quiet --show-progress https://gist.githubusercontent.com/remkop/4d0339d9a7f80fa848735bec745d203a/raw/8a3fcaf698b44a3a721e1ba800674cbb1a435e29/FileList.java
# download dependencies
wget --quiet --show-progress https://github.com/remkop/picocli/releases/download/v4.1.4/picocli-4.1.4.jar
wget --quiet --show-progress https://github.com/remkop/picocli/releases/download/v4.1.4/picocli-codegen-4.1.4.jar
# compile and generate native-image configuration files
mkdir classes
javac -d classes -cp picocli-4.1.4.jar:picocli-codegen-4.1.4.jar FileList.java
# inspect result
tree
# build native image
native-image -cp classes:picocli-4.1.4.jar FileList
# execute: basic usage
./filelist -h
./filelist --version
./filelist
./filelist -r -S SIZE
# install command line completion for this command
. <(./filelist generate-completion)
# use completion
./filelist -<TAB>
*/
import picocli.AutoComplete;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import java.io.File;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.concurrent.Callable;
import java.util.function.Consumer;
@Command(name = "filelist", mixinStandardHelpOptions = true,
description = {
"List information about the <file> (the current directory by default).",
"Sort entries alphabetically if no other sort order is specified." },
version = {
"filelist 2.0",
"Picocli " + picocli.CommandLine.VERSION,
"JVM: ${java.version} (${java.vendor} ${java.vm.name} ${java.vm.version})",
"OS: ${os.name} ${os.version} ${os.arch}"},
subcommands = AutoComplete.GenerateCompletion.class)
public class FileList implements Callable<Integer> {
@Parameters(index = "0", defaultValue = ".", description = "The file to list.")
private File file;
@Option(names = {"-S", "--sort"},
description = "Sort order. One of: ${COMPLETION-CANDIDATES}. Default value: ${DEFAULT-VALUE}.")
private Sort sort = Sort.NAME;
@Option(names = {"-r", "--reverse"}, description = "Reverse order while sorting.")
private boolean reverse;
public static void main(String... args) {
System.exit(new CommandLine(new FileList()).execute(args));
}
@Override
public Integer call() throws Exception {
Comparator<File> order = reverse ? sort.order.reversed() : sort.order;
Arrays.stream(file.listFiles()).sorted(order).forEach(f ->
System.out.printf("%2$10d %3$tb %3$2te %3$tY %3$tH:%3$tM %1$s%n",
f.getName(), f.length(), new Date(f.lastModified()))
);
return 0;
}
enum Sort {
NONE((f1, f2) -> 0),
SIZE((f1, f2) -> Long.compare(f1.length(), f2.length())),
NAME((f1, f2) -> f1.getName().compareTo(f2.getName())),
TIME((f1, f2) -> Long.compare(f1.lastModified(), f2.lastModified())),
;
public final Comparator<File> order;
Sort(Comparator<File> c) { order = c; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment