Vert.x内核模块 结束



Vert.x命令行接口API

Vert.x内核模块提供一个用向程序传递命令行参数的API。此API也可以打印出命令行工具可获取选项的详细帮助信息。既使此特性与Vert.x核心主题相差甚远,此APfat jarLauncher类中使用,并且也在vertx命令行工具中使用。此外此API支持多语言(在支持的语言中使用)并且在Vert.x Shell中被使用。

Vert.x CLI提供了用于描述命令行接口的模型和一个解析器。此解析器支持不同的语法:

  • POSIX选项(如tar–zxvf foo.tar.gz

  • GNU长选项(如du–human-readable –max-depth=1

  • 类似Java属性(如. java-Djava.awt.headless=true -Djava.net.useSystemProxies=true Foo

  • 伴有附加的值的短选项(例gcc -O2 foo.c

  • 但一连字号的长选项(如ant –projecthelp

使用CLI API有三步骤:

  1. 命令行接口的定义

  2. 用户命令行的解析

  3. 查询和提问

定义阶段

每个命令号接口必须定义一组将被使用的选项和参数。CLI AIP使用OptionArgument类描术选项和参数:
CLI cli = CLI.create("copy")

   .setSummary("A command line interface to copy files.")

   .addOption(new Option()

       .setLongName("directory")

       .setShortName("R")

       .setDescription("enables directory support")

       .setFlag(true))

   .addArgument(new Argument()

       .setIndex(0)

       .setDescription("The source")

       .setArgName("source"))

   .addArgument(new Argument()

       .setIndex(0)

       .setDescription("The destination")

       .setArgName("target"));

如我所见,可以用CLI.create方法创建一个CLI。传入的字符串是一个CLI名称。一旦创建,就可以设置概述和描述了。概术规定为一行较短文件,然而描述可包含更加详细信息。每个选项和参数在调用CLI对象的addArgumentaddOption方法被添加。

 选项

一个选项是一个用关键字标识的存在与用户命令行的命令行参数。选项至少必须有一个长名称和一个知名称。长名称通常使用前缀,然而短名称用于单一的­中划线(-)。选项能得到关于用法的可显示信息。选项可接收01或多个值。一个选项接收0个值是一个标识,要用setFlag进行声名。默认的,选项接收单一值,可以用setMultiValued方法配置选项接收多个值。

CLI cli = CLI.create("some-name")

   .setSummary("A command line interface illustrating the optionsvaluation.")

   .addOption(new Option()

       .setLongName("flag").setShortName("f").setFlag(true).setDescription("aflag"))

   .addOption(new Option()

       .setLongName("single").setShortName("s").setDescription("asingle-valued option"))

   .addOption(new Option()

       .setLongName("multiple").setShortName("m").setMultiValued(true)

       .setDescription("a multi-valued option"));

选项可以被标记为强制要求的,一个强制要求的选项没有在命令行上设置,将会在解析过程中抛出异常:

CLI cli = CLI.create("some-name")

   .addOption(new Option()

       .setLongName("mandatory")

       .setRequired(true)

       .setDescription("a mandatory option"));

非强制选项有一个默认值,如果用户在命令行上没有设置,将使用此默认值。

CLI cli = CLI.create("some-name")

   .addOption(new Option()

       .setLongName("optional")

       .setDefaultValue("hello")

       .setDescription("an optional option with a default value"));

选项使用setHidden方法可以隐藏。隐藏选项不会在用法中显示,但是仍然能在用户命令行中使用(仅用于超级用户)。

如果选项值限定为固定集合,可以设置不同的接收选项:

CLI cli = CLI.create("some-name")

   .addOption(new Option()

       .setLongName("color")

       .setDefaultValue("green")

       .addChoice("blue").addChoice("red").addChoice("green")

       .setDescription("a color"));

选项也可以用JSON形式初始化。

 参数

与选项不同,参数没有键,仅用他们的索引进行标识。例如java com.acme.Foo

com.acme.Foo是一个参数。参数没有名称,用基于0的索引进行标识,第一个参数索引为0

CLI cli = CLI.create("some-name")

   //will have the index 0

   .addArgument(new Argument()

       .setDescription("the first argument")

       .setArgName("arg1"))

   //will have the index 1

   .addArgument(new Argument()

       .setDescription("the second argument")

       .setArgName("arg2"));

argName是可选反并在用户信息中使用。

作为选项,Argument可以:

  • setHidden被隐藏。

  • setRequired被强制要求

  • setDefaultValue设置默认值

  • setMultiValued设置接收多个值,仅最后一个参数允许有多个值。

参数可以从JSON格式初始化。

 

用法信息生成

一旦CLI实例配置完成,就可以生成用法信息了:

CLI cli = CLI.create("copy")

   .setSummary("A command line interface to copy files.")

   .addOption(new Option()

       .setLongName("directory")

       .setShortName("R")

       .setDescription("enables directory support")

       .setFlag(true))

   .addArgument(new Argument()

       .setIndex(0)

       .setDescription("The source")

       .setArgName("source"))

   .addArgument(new Argument()

       .setIndex(0)

       .setDescription("The destination")

       .setArgName("target"));

 

StringBuilder builder = new StringBuilder();

cli.usage(builder);

产生的用法信息如下:

Usage: copy [-R] source target

 

A command line interface to copy files.

 

 -R,--directory  enables directorysupport

如果需要调试用法信息,检查UsageMessageFormatter类。

 

解析阶段

一旦CLI实例配置好,就可以解析用户命令行了,并分析每个选项和参数:

CommandLine commandLine =cli.parse(userCommandLineArguments);

 

parse方法返回一个包含值的CommandLine对象。默认的,CommandLine对象验证用户命令行并且检查每个强制选项和参数是否被设置,检查收到的每个选项的的值的个数。也可以传入false作为parse方法第二个参数禁用验证。这对于检查一个选项或者参数是否存在,和传入的命令行是不有效是有帮助的。也可以用CommandLineisValid方法检查是否有效。

 

查询/提问阶段

一旦解析,就可得到由pase方法返回CommnadLine对象中选项和参数的值:

CommandLine commandLine =cli.parse(userCommandLineArguments);

String opt =commandLine.getOptionValue("my-option");

boolean flag =commandLine.isFlagEnabled("my-flag");

String arg0 = commandLine.getArgumentValue(0);

如果有一个选项标识为“help”,并启用“help”选项,那么验证不会失败,但是会给予是否检查帮助信息的机会。

CLI cli = CLI.create("test")

   .addOption(

       newOption().setLongName("help").setShortName("h").setFlag(true).setHelp(true))

   .addOption(

       new Option().setLongName("mandatory").setRequired(true));

 

CommandLine line =cli.parse(Collections.singletonList("-h"));

 

// The parsing does not fail and let you do:

if (!line.isValid() &&line.isAskingForHelp()) {

 StringBuilder builder = new StringBuilder();

 cli.usage(builder);

 stream.print(builder.toString());

}

 

输入选项和参数

上面说明的OptionArgument类不必输入,意示着仅需要字符串值。

TypedOptionTypedArgument让你指定类型,所以原如字符串值被转成指定类型。在CLI定义中用TypedOptionTypedArgument替代OptiontArgument

CLI cli = CLI.create("copy")

   .setSummary("A command line interface to copy files.")

   .addOption(new TypedOption<Boolean>()

       .setType(Boolean.class)

       .setLongName("directory")

       .setShortName("R")

       .setDescription("enables directory support")

       .setFlag(true))

   .addArgument(new TypedArgument<File>()

       .setType(File.class)

       .setIndex(0)

       .setDescription("The source")

       .setArgName("source"))

   .addArgument(new TypedArgument<File>()

       .setType(File.class)

       .setIndex(0)

       .setDescription("The destination")

       .setArgName("target"));

然后你可以象下面这样接收转换后的值:

CommandLine commandLine =cli.parse(userCommandLineArguments);

boolean flag =commandLine.getOptionValue("R");

File source = commandLine.getArgumentValue("source");

File target =commandLine.getArgumentValue("target");

Vert.x CLI也可以转换成类:

  • 有一个单一字符串参数的构造器,与FileJsonObject类似

  • 俱有静态fromfromString方法

  • 具有静态valueOf方法,如基本类型和枚举类型

此外,也可以实现自己的转换器Converter并且让CLI使用此转换器:

CLI cli = CLI.create("some-name")

   .addOption(new TypedOption<Person>()

       .setType(Person.class)

       .setConverter(new PersonConverter())

       .setLongName("person"));

对于布尔值,布尔值可以被解析成true:on,yes,1,true。如果一个选项用enum作为类型,CLI将会自动计算选择的集合。

 

使用注解

也可以用注解定义CLI。在类或者setter方法上使用注解进行定义:

@Name("some-name")

@Summary("some short summary.")

@Description("some long description")

public class AnnotatedCli {

 

 privateboolean flag;

 privateString name;

 privateString arg;

 

 @Option(shortName = "f", flag =true)

 publicvoid setFlag(boolean flag) {

  this.flag = flag;

 }

 

 @Option(longName = "name")

 publicvoid setName(String name) {

  this.name = name;

 }

 

 @Argument(index = 0)

 publicvoid setArg(String arg) {

 this.arg = arg;

 }

}

注解完成,可以定义CLI并且注入值:
CLI cli = CLI.create(AnnotatedCli.class);

CommandLine commandLine =cli.parse(userCommandLineArguments);

AnnotatedCli instance = new AnnotatedCli();

CLIConfigurator.inject(commandLine, instance);

 

Vert.x启动器

Vert.x启动器(Launcher)被用于fat jar中的启动类,Launcher也被用在命令行工具中。Launcher执一个命令的集合,如run,bare,star…

 

扩展Vert.x启动器

仅可以在Java中,通过实现自己的Command扩展命令集:

@Name("my-command")

@Summary("A simple hello command.")

public class MyCommand extends DefaultCommand {

 

 privateString name;

 

 @Option(longName = "name", required = true)

 publicvoid setName(String n) {

   this.name = n;

 }

 

 @Override

 publicvoid run() throws CLIException {

   System.out.println("Hello " + name);

 }

}

并需要实现一个CommandFactory:

public class HelloCommandFactory extendsDefaultCommandFactory<HelloCommand> {

 publicHelloCommandFactory() {

  super(HelloCommand.class);

 }

}

然后创建src/main/resources/META-INF/services/io.vertx.core.spi.launcher.CommandFactory文件,并加一行用于指定完整有效的工厂名称

io.vertx.core.launcher.example.HelloCommandFactory

生成包含命令的jar包。并确定包含SPI文件

(META-INF/services/io.vertx.core.spi.launcher.CommandFactory)

然后将包含命令的jar放到fat-jar的类路径或者Vert.x发布的lib目录中,然后可以这样执行:

vertx hello vert.x

java -jar my-fat-jar.jar hello vert.x

 

fat ja中使用Launcher

为了在fat-jar中使用Launcher类,可以将MwgkANIFEST文件中的Main-Class设置为io.vertx.core.Launcher。此外设置MANIFESTMain-Verticle到主verticle

 

默认,Launcher执行run命令。然而,也可以在MAINFEST中设置Main-Command作为默认命令。如果启动fat-jar没有提供命令时请用默认命令。

 

Launcher子类

也可以创建一个Launcher的子类启动应用。此类被设计成极易扩展。一个Launcher的子类可以:

  • beforeStartingVertx方法定制vert.x配置

  • 重写afterStartingVertx获取通过run,bare命令创建的实例。

  • getMainVerticlegetDefaultCommand命令配置默认的verticle和命令。

  • registerunregister方法添加/移除命令

 

启动和退出码

在用Launcher类作为主类时,将会用到下面退出码:

  • 0,进程平滑结束或者一个未捕获的异常被抛出

  • 1,通用错误

  • 11Vert.x不能初始化

  • 12,大量进程不能启动,发现和关闭,此错误被用于start,stop命令

  • 14,系统配置不满足系统要求(如没找到java

  • 15,主verticle不能被布署。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值