Guide to User-defined Commands

用户定义的命令允许您向 Spring CLI 添加自定义命令。命令的目录结构表示引入 shell 的命令和子命令。 例如,controller\new 的目录结构在 CLI 中会转换为命令 controller new。 位于子命令目录的文件有:

  • 一个名为 command.yaml 的文件,它描述了该命令及其参数。

  • 一个或多个描述将代码或配置添加到项目所需的步骤的操作文件。

用户定义的命令使用以下命令向 CLI 注册:

command add --from <repository-url>

该存储库的内容将复制到您现有的项目中。 例如,查看 [role="bare"][role="bare"]https://github.com/rd-1-2022/udc-spring-controller 存储库的内容。

Structure

所有用户定义命令的目录结构位于以下路径下:

.spring/commands

因此,对于前面提到的用户定义命令 controller new 来说,其中存放着命令描述文件和操作文件的完整目录结构为:

.spring/commands/controller/new

在此目录中,您可以定义:

  • 描述了该命令的功能和命令参数的 command.yaml 文件。

  • 一个或多个定义针对此命令运行的步骤的操作文件。

例如,[role="bare"][role="bare"]https://github.com/rd-1-2022/udc-spring-controller 存储库的目录内容如下:

.
├── README.adoc
└── .spring
    └── commands
        └── controller
            └── new
                ├── command.yaml
                ├── create-controller.yaml
                └── RestController.java

Describing the Command

此前提到的 controller new 命令的 command.yaml 文件内容如下:

command:
  description: Generate a new Spring Controller
  options:
    #
    - name: feature
      description: name of the feature package
      dataType: string
      defaultValue: person
      inputType: text
      required: true

该文件包含命令的简要说明和一系列命令行选项。

选项的 name 是必需的。默认 dataTypestring

dataType 可以是 intintegerboolbooleandoublefloatlongshortstring

Spring CLI 在运行时合并这些命令,当向其询问通用帮助以及特定命令的帮助时,它们便会出现。以下清单展示了一个示例:

$spring help

<output truncated>

User-defined Commands
       controller new: Generate a new Spring Controller

以下清单展示了第二个示例:

$ spring help controller new
NAME
       controller new - Generate a new Spring Controller

SYNOPSIS
       controller new --feature String

OPTIONS
       --feature String
       name of the feature package
       [Optional, default = person]

Action Files

操作文件构建方式与 GitHub 操作文件类似。

操作文件可以自定义命名。CLI 查找带有 .yaml.yml 文件扩展名的文件。

可以根据自己需要创建任意数量的操作文件来完成特定任务。操作文件运行的顺序是深度优先,然后是按字母顺序。

以下清单展示了一个简单的示例:

actions:
  - generate:
      to: hello.txt
      text: Hello at {{now}} on {{os-name}}.

此操作在当前工作目录中生成一个名为 hello.txt 的文件(如果该文件还不存在)。模板内容包含连字符分隔的变量名。

user-nameos-name 变量来自 Java 系统属性,并且会自动在模板引擎中进行注册。now 变量是在运行命令时 new java.util.Date() 的值。

作为一个更真实的创建 Java 代码的示例,以下三个清单显示了名为 Controller.java 的动作文件的目录内容及其在存储库 [role="bare"][role="bare"]https://github.com/rd-1-2022/udc-spring-controller 中的相关动作和模板化 Java 文件。feature 变量是一个命令选项。

  • Command File

command:
  description: Generate a new Spring Controller
  options:
    #
    - name: feature
      description: name of the feature package
      dataType: string
      defaultValue: person
      inputType: text
  • Action File

actions:
  - generate:
      to: src/main/java/{{root-package-dir}}/{{feature}}/{{capitalizeFirst feature}}Controller.java
      from: RestController.java

to: 字段定义待生成文件的位置。

如果待生成文件已经存在,则不会覆盖它,除非在与 to: 字段同一级添加了一个名为 overwrite: 的其他字段。

  • Templated Java File

package {{root-package}}.{{feature}};

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class {{capitalizeFirst feature}}Controller {

	@GetMapping("/{{feature}}")
	public String greeting() {
		return "Hello {{feature}}";
	}
}

所有命令行参数都作为变量传递给模板引擎。在此情况下,传递了 feature 选项。

一个有用的内置变量是 root-package-dir,它是包含 @SpringApplication 注解的类的目录。

Template Engine

模板引擎为 Handlebars。默认情况下,已注册多个 Handlebars 助手。

在前面的示例中,{{capitalizeFirst feature}} 模板变量是使用 Handlebars 辅助功能的示例。

默认情况下,会向模板引擎公开几个系统变量:

  • System.getProperties() 可用作 {{system-properties}}

  • System.getenv() 可用作 {{system-environment}}

  • 当前时间(由 new Date().toString() 定义)可用作 {{now}}

  • java.io.tmpdir 系统属性可用作 {{tmp-dir}}

  • file.separator 系统属性可用,形式为 {{file-separator}}* os.name 系统属性可用,形式为 {{os-name}}

  • user.name 系统属性可用,形式为 {{user.name}}

驻留 Spring Boot 主应用程序类的 Java 包名称作为 {{root-package}} 提供。

驻留 Spring Boot 主应用程序类的目录作为 {{root-package-dir}} 提供。

Maven 模型还公开了几个变量:

  • {{artifact-id}}

  • {{artifact-version}}

  • {{artifact-path}}

  • {{project-name}}

  • {{project-descriptoin}}

  • {{maven-model} - 这是 org.apache.maven.model.Model 类。

  • {{maven-properties}} - 这是一个 Java 属性对象,其键为 POM 的 &lt;properties&gt; 部分中每个条目的值。

  • {{java-version}} - 这是在 POM 中查找名为 java.version 的 Maven 属性。如果值为 1.8,则将其转换为 8 的值。

Creating a New User-defined Command

一个简单的入门方法是运行以下命令:

spring command new hello create

这会创建一个名为 hello 的用户定义命令,其中包含一个名为 create 的子命令。

可以通过运行 spring command new --help 来查看 spring command new 的完整选项集。以下清单显示输出:

$ spring command new --help
NAME
       command new - Create a new user-defined command

SYNOPSIS
       command new --commandName String --subCommandName String --path String --help

OPTIONS
       --commandName String
       The name of the user-defined command to create
       [Optional, default = hello]

       --subCommandName String
       The name of the user-defined sub-command to create
       [Optional, default = new]

       --path String
       Path to execute command in
       [Optional]

       --help or -h
       help for command new
       [Optional]

运行 spring command new hello create 会生成以下目录结构和文件。

.
├── README.adoc
└── .spring
    └── commands
        └── hello
            └── create
                ├── command.yaml
                └── hello.yaml

以下清单显示 command.yaml 文件的内容。它包含一个名为 greeting 的命令行参数。

command:
  description: Generate a new file with a hello message
  options:
    #
    - name: greeting
      description: who or what to say hello to
      dataType: string
      defaultValue: World
      inputType: text     # TEXT

以下清单显示名为 hello.yaml 的动作文件。它生成一个名为 hello.txt 的文件

actions:
  - generate:
      to: hello.txt
      text: Hello {{greeting}} at {{now}} on {{os-name}}.

当您运行 spring help 命令时,该命令会列在 自定义命令 标题下。

...
User-defined Commands
       hello create: Generate a new file with a hello message

运行 spring hello create 命令会生成 hello.txt 文件,其中包含以下内容:

Hello World at Mar 9, 2023 on Linux.

Learning more

Action Guide 描述了可在动作文件中(添加或修改项目中的代码和配置)使用的所有可用选项。