All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.micronaut.configuration.picocli.PicocliRunner Maven / Gradle / Ivy

There is a newer version: 5.6.0
Show newest version
/*
 * Copyright 2017-2019 original authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.micronaut.configuration.picocli;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.ApplicationContextBuilder;
import io.micronaut.context.env.CommandLinePropertySource;
import io.micronaut.context.env.Environment;
import io.micronaut.core.annotation.TypeHint;
import picocli.CommandLine;
import picocli.CommandLine.*;

import java.lang.reflect.Executable;
import java.lang.reflect.Parameter;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ResourceBundle;
import java.util.concurrent.Callable;

/**
 * Utility class with convenience methods for running picocli-based commands with
 * a micronaut application context.
 *
 * @author Remko Popma
 * @since 1.0
 */
@TypeHint(
    value = {System.class, Executable.class, Parameter.class, ResourceBundle.class, Path.class, Paths.class},
    typeNames = {"picocli.CommandLine$AutoHelpMixin", "picocli.CommandLine$Model$CommandSpec"},
    accessType = {TypeHint.AccessType.ALL_DECLARED_FIELDS, TypeHint.AccessType.ALL_PUBLIC_METHODS, TypeHint.AccessType.ALL_DECLARED_CONSTRUCTORS}
)
public class PicocliRunner {
    /**
     * Instantiates a new {@link ApplicationContext} for the {@link Environment#CLI} environment,
     * obtains an instance of the specified {@code Callable} command class from the context,
     * injecting any beans as required,
     * then parses the specified command line arguments, populating fields and methods annotated
     * with picocli {@link Option @Option} and {@link Parameters @Parameters}
     * annotations, and finally calls the command and returns the result.
     * 

* The {@code ApplicationContext} is {@linkplain ApplicationContext#close() closed} before this method returns. *

* @param cls the Callable command class * @param args the command line arguments * @param The callable type * @param The callable return type * @return {@code null} if an error occurred while parsing the command line options, * or if help was requested and printed. Otherwise returns the result of calling the Callable */ public static , T> T call(Class cls, String... args) { try (ApplicationContext ctx = ApplicationContext.builder(cls, Environment.CLI).start()) { return call(cls, ctx, args); } } /** * Obtains an instance of the specified {@code Callable} command class from the specified context, * injecting any beans from the specified context as required, * then parses the specified command line arguments, populating fields and methods annotated * with picocli {@link Option @Option} and {@link Parameters @Parameters} * annotations, and finally calls the command and returns the result. *

* The caller is responsible for {@linkplain ApplicationContext#close() closing} the context. *

* @param cls the Callable command class * @param ctx the ApplicationContext that injects dependencies into the command * @param args the command line arguments * @param The callable type * @param The callable return type * @return {@code null} if an error occurred while parsing the command line options, * or if help was requested and printed. Otherwise returns the result of calling the Callable * @throws InitializationException if the specified command object does not have * a {@link Command}, {@link Option} or {@link Parameters} annotation * @throws ExecutionException if the Callable throws an exception */ public static , T> T call(Class cls, ApplicationContext ctx, String... args) { CommandLine commandLine = new CommandLine(cls, new MicronautFactory(ctx)); commandLine.execute(args); return commandLine.getExecutionResult(); } /** * Instantiates a new {@link ApplicationContext} for the {@link Environment#CLI} environment, * obtains an instance of the specified {@code Runnable} command class from the context, * injecting any beans as required, * then parses the specified command line arguments, populating fields and methods annotated * with picocli {@link Option @Option} and {@link Parameters @Parameters} * annotations, and finally runs the command. *

* The {@code ApplicationContext} is {@linkplain ApplicationContext#close() closed} before this method returns. *

* @param cls the Runnable command class * @param args the command line arguments * @param The runnable type * */ public static void run(Class cls, String... args) { ApplicationContextBuilder builder = buildApplicationContext(cls, args); try (ApplicationContext ctx = builder.start()) { run(cls, ctx, args); } } /** * Obtains an instance of the specified {@code Runnable} command class from the specified context, * injecting any beans from the specified context as required, * then parses the specified command line arguments, populating fields and methods annotated * with picocli {@link Option @Option} and {@link Parameters @Parameters} * annotations, and finally runs the command. *

* The caller is responsible for {@linkplain ApplicationContext#close() closing} the context. *

* @param cls the Runnable command class * @param ctx the ApplicationContext that injects dependencies into the command * @param args the command line arguments * @param The runnable type * @throws InitializationException if the specified command object does not have * a {@link Command}, {@link Option} or {@link Parameters} annotation * @throws ExecutionException if the Runnable throws an exception */ public static void run(Class cls, ApplicationContext ctx, String... args) { CommandLine commandLine = new CommandLine(cls, new MicronautFactory(ctx)); commandLine.execute(args); } /** * Instantiates a new {@link ApplicationContext} for the {@link Environment#CLI} environment, * obtains an instance of the specified {@code Callable} or {@code Runnable} command * class from the context, injecting any beans as required, * then parses the specified command line arguments, populating fields and methods annotated * with picocli {@link Option @Option} and {@link Parameters @Parameters} * annotations, and finally {@link CommandLine#execute(String...) executes} the command * and returns the resulting exit code. *

* The {@code ApplicationContext} is {@linkplain ApplicationContext#close() closed} before this method returns. *

* This is equivalent to: *

*
{@code
     * try (ApplicationContext context = ApplicationContext.builder(clazz, Environment.CLI).start()) {
     *     return new CommandLine(clazz, new MicronautFactory(context)).execute(args);
     * }
     * }
*

* Applications that need to customize picocli behavior by calling one of the setter * methods on the {@code CommandLine} instance should use code like the above instead of this method. * For example: *

*
{@code
     * // example of customizing picocli parser before invoking a command
     * try (ApplicationContext context = ApplicationContext.builder(clazz, Environment.CLI).start()) {
     *     return new CommandLine(clazz, new MicronautFactory(context)).
     *          setUsageHelpAutoWidth(true).
     *          setCaseInsensitiveEnumValuesAllowed(true).
     *          execute(args);
     * }
     * }
* @param clazz the Runnable or Callable command class * @param args the command line arguments * @return the exit code returned by {@link CommandLine#execute(String...)} */ public static int execute(Class clazz, String... args) { ApplicationContextBuilder builder = buildApplicationContext(clazz, args); try (ApplicationContext context = builder.start()) { return execute(clazz, context, args); } } /** * Obtains an instance of the specified {@code Callable} or {@code Runnable} command class * from the specified context, injecting any beans from the specified context as required, * then parses the specified command line arguments, populating fields and methods annotated * with picocli {@link Option @Option} and {@link Parameters @Parameters} * annotations, and finally {@link CommandLine#execute(String...) executes} the command * and returns the resulting exit code. *

* The caller is responsible for {@linkplain ApplicationContext#close() closing} the context. *

* This is equivalent to: *

*
{@code return new CommandLine(clazz, new MicronautFactory(context)).execute(args);}
* @param clazz the Runnable or Callable command class * @param context the ApplicationContext that injects dependencies into the command * @param args the command line arguments * @return the exit code returned by {@link CommandLine#execute(String...)} */ private static int execute(Class clazz, ApplicationContext context, String... args) { return new CommandLine(clazz, new MicronautFactory(context)).execute(args); } private static ApplicationContextBuilder buildApplicationContext(Class cls, String[] args) { io.micronaut.core.cli.CommandLine commandLine = io.micronaut.core.cli.CommandLine.parse(args); CommandLinePropertySource commandLinePropertySource = new CommandLinePropertySource(commandLine); return ApplicationContext .builder(cls, Environment.CLI) .propertySources(commandLinePropertySource); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy