Guide to User-defined Commands

User-defined commands let you add custom commands to the Spring CLI. The directory structure for commands represents the command and sub-command that are introduced into the shell.spring-doc.cn

For example, the directory structure of controller\new translates to the command controller new in the CLI.spring-doc.cn

The files located in the sub-command directory are:spring-doc.cn

  • A file named command.yaml that describes the command and its arguments.spring-doc.cn

  • One or more action files that describe the actions to take to add code or configuration to the project.spring-doc.cn

User-defined commands are registered with the CLI by using the following command:spring-doc.cn

command add --from <repository-url>

The contents of that repository are copied into your existing project.spring-doc.cn

For example, look at the contents of the github.com/rd-1-2022/udc-spring-controller repository.spring-doc.cn

Structure

The directory structure for all user-defined commands are under the following path:spring-doc.cn

.spring/commands

So, for the user defined command, controller new, mentioned previously, the full directory structure where the command description file and action files are located would be:spring-doc.cn

.spring/commands/controller/new

Inside this directory, you can define:spring-doc.cn

  • The command.yaml file that describes what the command does and the arguments of the command.spring-doc.cn

  • One or more action files that define the actions to run for this command.spring-doc.cn

For example, the directory contents of the github.com/rd-1-2022/udc-spring-controller repository are as follows:spring-doc.cn

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

Describing the Command

The contents of the command.yaml file for the controller new command mentioned previously are as follows:spring-doc.cn

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

The file contains a brief description of the command and an array of command line options.spring-doc.cn

The name of the options is required. The default dataType is string.spring-doc.cn

The dataType can be int, integer, bool, boolean, double, float, long, short, or string.spring-doc.cn

Spring CLI incorporates these commands at runtime, and they appear when asking for general help and command-specific help. The following listing shows an example:spring-doc.cn

$spring help

<output truncated>

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

The following listing show a second example:spring-doc.cn

$ 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

Action files are structured similarly to GitHub action files.spring-doc.cn

Action files can be named anything you like. The CLI looks for files with .yaml and .yml file extensions.spring-doc.cn

There can be as many action files as you need to accomplish a specific task. The order in which action files are run is depth-first and then alphabetical.spring-doc.cn

The following listing shows a simple example:spring-doc.cn

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

This action generates a file called hello.txt, if it does not already exist, in the current working directory. The template contents contain kebab-case variable names.spring-doc.cn

The user-name and os-name variables come from Java system properties and are automatically registered with the template engine. The now variable is the value of new java.util.Date() when the command was run.spring-doc.cn

As a more realistic example to create Java code, the following three listings show the contents of the action file named Controller.java and its related action and templated Java files in the repository github.com/rd-1-2022/udc-spring-controller. The feature variable is a command option.spring-doc.cn

command:
  description: Generate a new Spring Controller
  options:
    #
    - name: feature
      description: name of the feature package
      dataType: string
      defaultValue: person
      inputType: text
actions:
  - generate:
      to: src/main/java/{{root-package-dir}}/{{feature}}/{{capitalizeFirst feature}}Controller.java
      from: RestController.java

The to: field defines the location of the file to be generated.spring-doc.cn

If the file to generate already exists, it is not overwritten unless an additional field named overwrite: is added at the same level as the to: field.spring-doc.cn

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}}";
	}
}

All command-line arguments are passed to the template engine as variables. In this case, the feature option is passed.spring-doc.cn

One useful built-in variable is root-package-dir, which is the directory where the class containing the @SpringApplication annotation is located.spring-doc.cn

Template Engine

The template engine is Handlebars. Several Handlebar helpers are registered by defaultspring-doc.cn

In the previous example, the {{capitalizeFirst feature}} template variable is an example of using a Handlebars helper.spring-doc.cn

By default, several system variables are exposed to the template engine:spring-doc.cn

  • System.getProperties() is available as {{system-properties}}spring-doc.cn

  • System.getenv() is available as {{system-environment}}spring-doc.cn

  • The current time (defined by new Date().toString()) is available as {{now}}spring-doc.cn

  • The java.io.tmpdir system property is available as {{tmp-dir}}spring-doc.cn

  • The file.separator system property is available as {{file-separator}}* The os.name system property is available as {{os-name}}spring-doc.cn

  • The user.name system property is available as {\{user.name}}spring-doc.cn

The Java package name where the Spring Boot main application class resides is available as {{root-package}}.spring-doc.cn

The directory where the Spring Boot main application class resides is available as {{root-package-dir}}.spring-doc.cn

The Maven model also exposes several variables:spring-doc.cn

Creating a New User-defined Command

A simple way to get started is to run the following command:spring-doc.cn

spring command new hello create

This creates a user-defined command named hello with a sub-command named create.spring-doc.cn

You can view the full set of options for spring command new by running spring command new --help. The following listing shows the output is:spring-doc.cn

$ 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]

Running spring command new hello create generates the following directory structure and files.spring-doc.cn

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

The following listing shows the contents of the command.yaml file. It contains one command line argument, named greeting.spring-doc.cn

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

The following listing shows the action file named hello.yaml. It generates the file named hello.txtspring-doc.cn

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

The command is listed under the User-defined Commands heading when you run the spring help command.spring-doc.cn

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

Running the spring hello create command generates the hello.txt file with the following contents:spring-doc.cn

Hello World at Mar 9, 2023 on Linux.

Learning more

The Action Guide describes all the options available for you to use in action files (to add or modify code and configuration to a project).spring-doc.cn