8. 组件
组件是一组功能,这些功能要么是内置的,要么是其他的 您可以根据自己的需要重复使用或扩展。有问题的组件是 内置命令或提供更高级别的 UI 端组件 命令本身的功能。
8.1. 内置命令
8.1.1. 帮助
运行 shell 应用程序通常意味着用户处于图形受限的
环境。此外,虽然在手机时代我们几乎总是保持连接,
访问 Web 浏览器或任何其他富 UI 应用程序(如 PDF 查看器)可能并不总是
是可能的。这就是为什么 shell 命令必须正确地自我记录很重要的原因,这就是命令的用武之地。help
键入 + 列出 shell 已知的所有命令(包括不可用的命令)
以及他们工作的简短描述,类似于以下内容:help
ENTER
my-shell:>help
AVAILABLE COMMANDS
Built-In Commands
exit: Exit the shell.
help: Display help about available commands
stacktrace: Display the full stacktrace of the last error.
clear: Clear the shell screen.
quit: Exit the shell.
history: Display or save the history of previously run commands
completion bash: Generate bash completion script
version: Show version info
script: Read and execute commands from a file.
键入 API 可显示有关命令的更多详细信息,包括可用参数、其
类型、是否为必填项以及其他详细信息。help <command>
下面的清单显示了应用于自身的命令:help
my-shell:>help help
NAME
help - Display help about available commands
SYNOPSIS
help --command String
OPTIONS
--command or -C String
The command to obtain help for.
[Optional]
帮助是模板化的,如果需要,可以进行自定义。设置位于可用于禁用命令、获取或希望通过展平来隐藏组的位置
结构,用于定义命令帮助输出的模板,用于定义
命令列表的输出。spring.shell.command.help
enabled
grouping-mode
group
flat
command-template
commands-template
如果已设置,则 help 将显示:spring.shell.command.help.grouping-mode=flat
my-shell:>help help
AVAILABLE COMMANDS
exit: Exit the shell.
help: Display help about available commands
stacktrace: Display the full stacktrace of the last error.
clear: Clear the shell screen.
quit: Exit the shell.
history: Display or save the history of previously run commands
completion bash: Generate bash completion script
version: Show version info
script: Read and execute commands from a file.
输出 和 都使用默认实现进行模板化
可以更改。help
help <commmand>
Option 默认为 model 并作为模型传递。spring.shell.command.help.commands-template
classpath:template/help-commands-default.stg
GroupsInfoModel
Option 默认为 model 并作为模型传递。spring.shell.command.help.command-template
classpath:template/help-command-default.stg
CommandInfoModel
钥匙 | 描述 |
---|---|
|
|
|
commands 变量(请参阅 GroupCommandInfoModel 变量)。 |
|
commands 变量(请参阅 CommandInfoModel 变量)。 |
|
|
钥匙 | 描述 |
---|---|
|
组的名称(如果已设置)。否则为空。 |
|
命令 (如果已设置)。否则为空。Type 是多值,请参阅 CommandInfoModel 变量。 |
钥匙 | 描述 |
---|---|
|
命令的名称(如果已设置)。否则为 null。类型为 string 并包含 full 命令。 |
|
命令的名称(如果已设置)。否则为 null。类型是多值,基本上是拆分的。 |
|
可能的别名(如果已设置)。类型是带字符串的多值。 |
|
命令的描述(如果已设置)。否则为 null。 |
|
parameters 变量(如果已设置)。否则为空。Type 是多值,请参阅 CommandParameterInfoModel 变量。 |
|
可用性变量(请参阅 CommandAvailabilityInfoModel 变量)。 |
钥匙 | 描述 |
---|---|
|
参数的类型(如果已设置)。否则为 null。 |
|
参数(如果已设置)。否则为 null。类型是带字符串的多值。 |
|
|
|
参数的描述 (如果已设置)。否则为 null。 |
|
参数的默认值 (如果已设置)。否则为 null。 |
|
|
钥匙 | 描述 |
---|---|
|
|
|
如果设置了 not available (如果已设置),则为原因。否则为 null。 |
8.1.3. 退出
该命令(也称为别名为 )请求 shell 正常退出
关闭 Spring 应用程序上下文。如果未覆盖,则 JLine bean 会写入所有
命令复制到磁盘,以便它们在下次启动时再次可用。quit
exit
History
8.1.4. 堆栈跟踪
当命令代码中发生异常时,shell 会捕获该异常,并显示一条简单的单行消息 以免用户收到太多信息。 但是,在某些情况下,了解到底发生了什么很重要(尤其是在异常具有嵌套原因时)。
为此, Spring Shell 会记住上次发生的异常,用户稍后可以使用该命令在控制台上打印所有详细信息。stacktrace
8.1.5. 脚本
该命令接受本地文件作为参数,并重放在其中找到的命令,一次重放一个命令。script
从文件中读取的行为与在交互式 shell 中完全一样,因此会考虑以
作为注释并被忽略,而以 trigger line continuation 结尾的行。//
\
8.1.6. 历史
该命令显示已执行的命令的历史记录。history
您可以使用一些配置选项来配置行为
的历史。历史记录保存在日志文件中,该文件默认处于启用状态,并且可以
通过设置 来关闭。日志文件的名称
解析自 ,默认为 ,
您可以通过设置 来更改。spring.shell.history.enabled
spring.application.name
spring-shell.log
spring.shell.history.name
默认情况下,将生成一个日志文件到当前工作目录,您可以指定该目录
通过设置 .此属性可以包含
placeholder () ),解析为通用共享配置目录。spring.shell.config.location
{userconfig}
运行 Spring Shell 应用程序,查看示例应用程序在使用这些选项时的工作原理。 |
8.1.7. 完成
命令集允许您创建可以使用的脚本文件
使用 AM OS shell 实现来提供补全。这在以下情况下非常有用
使用非交互模式。completion
目前,唯一的实现是 bash,它与 sub-command 一起使用。bash
8.1.8. 版本
该命令通过集成到
Boot,如果它们存在于 shell 应用程序中。
默认情况下,只显示版本信息,您可以通过配置启用其他信息
选项。version
BuildProperties
GitProperties
相关设置位于 下,您可以在其中使用
禁用命令,并可选择使用 定义您自己的模板。您可以使用 、 、 、 、 和 命令来控制
字段。spring.shell.command.version
enabled
template
show-build-artifact
show-build-group
show-build-name
show-build-time
show-build-version
show-git-branch
show-git-commit-id
show-git-short-commit-id
show-git-commit-time
模板默认为 ,您可以定义
您自己的,如下例所示:classpath:template/version-default.st
<buildVersion>
此设置将输出如下内容:
X.X.X
您可以将以下属性添加到默认模板渲染中:、、、、 和 。buildVersion
buildGroup
buildGroup
buildName
buildTime
gitShortCommitId
gitCommitId
gitBranch
gitCommitTime
8.2. 流程
当您使用流组件构建涉及
使用多个组件,您的实现可能会变得有点混乱。
为了简化这些用例,我们添加了一个可以将多个组件执行挂接在一起的
作为 “flow” 进行。ComponentFlow
以下清单显示了 shell 中的流及其输出的示例:
static class FlowSampleComplex {
@Autowired
private ComponentFlow.Builder componentFlowBuilder;
public void runFlow() {
Map<String, String> single1SelectItems = new HashMap<>();
single1SelectItems.put("key1", "value1");
single1SelectItems.put("key2", "value2");
List<SelectItem> multi1SelectItems = Arrays.asList(SelectItem.of("key1", "value1"),
SelectItem.of("key2", "value2"), SelectItem.of("key3", "value3"));
ComponentFlow flow = componentFlowBuilder.clone().reset()
.withStringInput("field1")
.name("Field1")
.defaultValue("defaultField1Value")
.and()
.withStringInput("field2")
.name("Field2")
.and()
.withConfirmationInput("confirmation1")
.name("Confirmation1")
.and()
.withPathInput("path1")
.name("Path1")
.and()
.withSingleItemSelector("single1")
.name("Single1")
.selectItems(single1SelectItems)
.and()
.withMultiItemSelector("multi1")
.name("Multi1")
.selectItems(multi1SelectItems)
.and()
.build();
flow.run();
}
}
组件的正常执行顺序与使用 builder 定义的 Sequence 相同。它
可以通过使用函数并返回目标组件 ID 来有条件地选择跳转到流中的位置。如果返回的 id 为 aither null 或不存在,则 flow 基本上会在那里停止。next
static class FlowSampleConditional {
@Autowired
private ComponentFlow.Builder componentFlowBuilder;
public void runFlow() {
Map<String, String> single1SelectItems = new HashMap<>();
single1SelectItems.put("Field1", "field1");
single1SelectItems.put("Field2", "field2");
ComponentFlow flow = componentFlowBuilder.clone().reset()
.withSingleItemSelector("single1")
.name("Single1")
.selectItems(single1SelectItems)
.next(ctx -> ctx.getResultItem().get().getItem())
.and()
.withStringInput("field1")
.name("Field1")
.defaultValue("defaultField1Value")
.next(ctx -> null)
.and()
.withStringInput("field2")
.name("Field2")
.defaultValue("defaultField2Value")
.next(ctx -> null)
.and()
.build();
flow.run();
}
}
运行流的结果返回 ,您可以
用于执行进一步的操作。ComponentFlowResult |
8.3. 流组件
从版本 2.1.x 开始,新的组件模型提供了 为常见用例创建更高级别用户交互的更简单方法, 例如以各种形式征求意见。这些通常只是纯文本 input 或从列表中选择内容。
内置组件的模板位于 Classpath 中。org/springframework/shell/component
内置组件通常遵循以下逻辑:
-
输入用户输入的运行循环。
-
生成与组件相关的上下文。
-
呈现组件状态的运行时状态。
-
退出。
-
渲染组件状态的最终状态。
Flow 为定义 更适合定义交互式命令流的组件。 |
8.3.1. 组件渲染
您可以通过以下两种方式之一实现组件渲染:完全
以编程方式或使用 ANTLR String模板。
严格来说,有一个简单的渲染器接口
,该 ID 将 .
这使您可以在 templating 和 code 之间进行选择。Function
Context
AttributedString
如果您不需要执行任何复杂或 您只想稍微修改现有的组件布局。渲染 然后,THROUGH CODE 让您可以灵活地执行任何需要的操作。
渲染的编程方式是创建一个 :Function
class StringInputCustomRenderer implements Function<StringInputContext, List<AttributedString>> {
@Override
public List<AttributedString> apply(StringInputContext context) {
AttributedStringBuilder builder = new AttributedStringBuilder();
builder.append(context.getName());
builder.append(" ");
if (context.getResultValue() != null) {
builder.append(context.getResultValue());
}
else {
String input = context.getInput();
if (StringUtils.hasText(input)) {
builder.append(input);
}
else {
builder.append("[Default " + context.getDefaultValue() + "]");
}
}
return Arrays.asList(builder.toAttributedString());
}
}
然后你可以将其挂接到一个组件上:
@ShellMethod(key = "component stringcustom", value = "String input", group = "Components")
public String stringInputCustom(boolean mask) {
StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue",
new StringInputCustomRenderer());
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
if (mask) {
component.setMaskCharacter('*');
}
StringInputContext context = component.run(StringInputContext.empty());
return "Got value " + context.getResultValue();
}
组件有自己的上下文,但通常共享一些功能 从父组件 types.下表显示了这些上下文变量:
钥匙 | 描述 |
---|---|
|
组件呈现其结果后的值。 |
|
组件的名称 — 即其标题。 |
|
组件的可能消息集。 |
|
消息的级别 — 、 、 或 。 |
|
如果 level 为 ,则返回 。否则为 false。 |
|
如果 level 为 ,则返回 。否则为 false。 |
|
如果 level 为 ,则返回 。否则为 false。 |
|
原始用户输入。 |
钥匙 | 描述 |
---|---|
|
组件的名称 — 即其标题。 |
|
原始用户输入 — 主要用于筛选。 |
|
项状态的完整列表。 |
|
项状态的可见列表。 |
|
如果上下文处于 result 模式,则返回。 |
|
选择器中的当前光标行。 |
8.3.2. 字符串输入
字符串输入组件要求用户提供简单的文本输入,并可选择屏蔽值 如果内容包含敏感内容。下面的清单显示了一个示例:
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component string", value = "String input", group = "Components")
public String stringInput(boolean mask) {
StringInput component = new StringInput(getTerminal(), "Enter value", "myvalue");
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
if (mask) {
component.setMaskCharacter('*');
}
StringInputContext context = component.run(StringInputContext.empty());
return "Got value " + context.getResultValue();
}
}
下图显示了字符串输入组件的典型输出:
上下文对象是 .下表列出了其 context 变量:StringInputContext
钥匙 | 描述 |
---|---|
|
默认值 (如果已设置)。否则为 null。 |
|
掩码输入值 |
|
掩码结果值 |
|
遮罩字符(如果已设置)。否则为 null。 |
|
|
|
父上下文变量(请参阅 TextComponentContext 模板变量)。 |
8.3.3. 路径输入
path input 组件向用户请求 a 并提供有关路径本身的其他信息。Path
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component path", value = "Path input", group = "Components")
public String pathInput() {
PathInput component = new PathInput(getTerminal(), "Enter value");
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
PathInputContext context = component.run(PathInputContext.empty());
return "Got value " + context.getResultValue();
}
}
下图显示了 path input 组件的典型输出:
上下文对象是 .下表描述了其上下文变量:PathInputContext
钥匙 | 描述 |
---|---|
|
父上下文变量(请参阅 TextComponentContext 模板变量)。 |
8.3.4. 确认
确认组件要求用户进行简单确认。它本质上是一个 是或否问题。
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component confirmation", value = "Confirmation input", group = "Components")
public String confirmationInput(boolean no) {
ConfirmationInput component = new ConfirmationInput(getTerminal(), "Enter value", !no);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
ConfirmationInputContext context = component.run(ConfirmationInputContext.empty());
return "Got value " + context.getResultValue();
}
}
下图显示了确认组件的典型输出:
上下文对象是 .下表描述了其上下文变量:ConfirmationInputContext
钥匙 | 描述 |
---|---|
|
默认值 — 或 。 |
|
父上下文变量(请参阅 TextComponentContext 模板变量)。 |
8.3.5. 单选
单个 select 组件要求用户从列表中选择一个项目。它类似于简单的 Dropbox 实现。下面的清单显示了一个示例:
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component single", value = "Single selector", group = "Components")
public String singleSelector() {
SelectorItem<String> i1 = SelectorItem.of("key1", "value1");
SelectorItem<String> i2 = SelectorItem.of("key2", "value2");
List<SelectorItem<String>> items = Arrays.asList(i1, i2);
SingleItemSelector<String, SelectorItem<String>> component = new SingleItemSelector<>(getTerminal(),
items, "testSimple", null);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
SingleItemSelectorContext<String, SelectorItem<String>> context = component
.run(SingleItemSelectorContext.empty());
String result = context.getResultItem().flatMap(si -> Optional.ofNullable(si.getItem())).get();
return "Got value " + result;
}
}
下图显示了单个 select 组件的典型输出:
上下文对象是 .下表描述了其上下文变量:SingleItemSelectorContext
钥匙 | 描述 |
---|---|
|
组件存在时的返回值。 |
|
可见项,其中 rows 包含名称和选定项的映射。 |
|
父上下文变量(请参阅 SelectorComponentContext 模板变量)。 |
您可以通过定义项目来预先选择项目以进行公开。这是
如果您知道 default 并允许用户仅按 进行选择,则很有用。
下面的清单设置了一个默认值:Enter
SelectorItem<String> i1 = SelectorItem.of("key1", "value1");
SelectorItem<String> i2 = SelectorItem.of("key2", "value2");
List<SelectorItem<String>> items = Arrays.asList(i1, i2);
SingleItemSelector<String, SelectorItem<String>> component = new SingleItemSelector<>(getTerminal(),
items, "testSimple", null);
component.setDefaultExpose(i2);
8.3.6. 多选
多选组件要求用户从列表中选择多个项目。 下面的清单显示了一个示例:
@ShellComponent
public class ComponentCommands extends AbstractShellComponent {
@ShellMethod(key = "component multi", value = "Multi selector", group = "Components")
public String multiSelector() {
List<SelectorItem<String>> items = new ArrayList<>();
items.add(SelectorItem.of("key1", "value1"));
items.add(SelectorItem.of("key2", "value2", false, true));
items.add(SelectorItem.of("key3", "value3"));
MultiItemSelector<String, SelectorItem<String>> component = new MultiItemSelector<>(getTerminal(),
items, "testSimple", null);
component.setResourceLoader(getResourceLoader());
component.setTemplateExecutor(getTemplateExecutor());
MultiItemSelectorContext<String, SelectorItem<String>> context = component
.run(MultiItemSelectorContext.empty());
String result = context.getResultItems().stream()
.map(si -> si.getItem())
.collect(Collectors.joining(","));
return "Got value " + result;
}
}
下图显示了一个典型的多选组件:
上下文对象是 .下表描述了其上下文变量:MultiItemSelectorContext
钥匙 | 描述 |
---|---|
|
组件存在时返回的值。 |
|
可见项,其中行包含 name、selected、on-row 和 enabled 项的映射。 |
|
父上下文变量(请参阅 SelectorComponentContext 模板变量)。 |