golang创建交互式命令行提示链插件库strumt的使用
Golang创建交互式命令行提示链插件库strumt的使用
Strumt是一个用于创建提示链的库。它提供以下功能:
- 多行提示
- 输入验证
- 出错重试
- 创建类型安全的提示
- 自定义提示和错误显示
- 记录提示会话
- 轻松测试提示场景
示例代码
下面是一个完整的示例,展示如何使用strumt创建一个交互式命令行提示链来收集用户信息:
package main
import (
"bufio"
"fmt"
"os"
"strconv"
"github.com/antham/strumt"
)
func main() {
user := User{}
// 创建prompt实例,从标准输入读取,输出到标准输出
p := strumt.NewPromptsFromReaderAndWriter(bufio.NewReader(os.Stdin), os.Stdout)
// 添加三个提示器
p.AddLinePrompter(&StringPrompt{&user.FirstName, "Enter your first name", "userName", "lastName", "userName"})
p.AddLinePrompter(&StringPrompt{&user.LastName, "Enter your last name", "lastName", "age", "lastName"})
p.AddLinePrompter(&IntPrompt{&user.Age, "Enter your age", "age", "", "age"})
// 设置第一个提示的ID
p.SetFirst("userName")
// 运行提示链
p.Run()
// 打印会话记录
for _, step := range p.Scenario() {
fmt.Println(step.PromptString())
fmt.Println(step.Inputs()[0])
if step.Error() != nil {
fmt.Println(step.Error())
}
}
fmt.Println()
fmt.Printf("User datas : %#v", user)
}
// 字符串提示器结构体
type StringPrompt struct {
store *string // 存储用户输入的指针
prompt string // 提示文本
currentID string // 当前提示ID
nextPrompt string // 成功后的下一个提示ID
nextPromptOnError string // 出错后的下一个提示ID
}
func (s *StringPrompt) ID() string {
return s.currentID
}
func (s *StringPrompt) PromptString() string {
return s.prompt
}
// 解析用户输入
func (s *StringPrompt) Parse(value string) error {
if value == "" {
return fmt.Errorf("Empty value given")
}
*(s.store) = value
return nil
}
func (s *StringPrompt) NextOnSuccess(value string) string {
return s.nextPrompt
}
func (s *StringPrompt) NextOnError(err error) string {
return s.nextPromptOnError
}
// 整数提示器结构体
type IntPrompt struct {
store *int
prompt string
currentID string
nextPrompt string
nextPromptOnError string
}
func (i *IntPrompt) ID() string {
return i.currentID
}
func (i *IntPrompt) PromptString() string {
return i.prompt
}
// 解析用户输入
func (i *IntPrompt) Parse(value string) error {
age, err := strconv.Atoi(value)
if err != nil {
return fmt.Errorf("%s is not a valid number", value)
}
if age <= 0 {
return fmt.Errorf("Give a valid age")
}
*(i.store) = age
return nil
}
func (i *IntPrompt) NextOnSuccess(value string) string {
return i.nextPrompt
}
func (i *IntPrompt) NextOnError(err error) string {
return i.nextPromptOnError
}
// 用户数据结构体
type User struct {
FirstName string
LastName string
Age int
}
代码说明
-
初始化:
- 创建
strumt.Prompts
实例,指定输入输出 - 添加三个提示器:两个字符串输入(姓名),一个整数输入(年龄)
- 创建
-
提示器结构:
StringPrompt
处理字符串输入IntPrompt
处理整数输入并验证有效性- 每个提示器实现
strumt.LinePrompter
接口
-
流程控制:
NextOnSuccess
定义成功后的下一个提示NextOnError
定义出错后的处理(通常是重试当前提示)SetFirst
设置起始提示ID
-
运行和结果:
Run()
启动提示链Scenario()
获取会话记录- 最后打印收集到的用户数据
这个示例展示了strumt的核心功能,包括输入验证、错误处理和提示链控制。你可以根据需要扩展更多的提示类型和验证逻辑。
更多关于golang创建交互式命令行提示链插件库strumt的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复
更多关于golang创建交互式命令行提示链插件库strumt的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
使用 strumt 创建交互式命令行工具
strumt 是一个 Go 语言的库,用于创建交互式命令行提示链工具。它允许你构建多步骤的交互式命令行界面,非常适合需要用户逐步输入信息的复杂 CLI 应用。
基本概念
strumt 的核心概念包括:
- Prompt:单个提示步骤
- Line:用户输入的一行内容
- Pipeline:将多个 Prompt 串联起来形成工作流
安装
go get github.com/antham/strumt
基础示例
下面是一个简单的交互式 CLI 示例:
package main
import (
"fmt"
"os"
"github.com/antham/strumt"
)
func main() {
p := strumt.NewPromptsFromReaderAndWriter(os.Stdin, os.Stdout)
// 添加第一个提示
p.AddLinePrompter(&strumt.BaseLinePrompter{
PromptString: "请输入您的名字: ",
Validator: func(input string) error {
if input == "" {
return fmt.Errorf("名字不能为空")
}
return nil
},
Next: func(answer string) strumt.Prompter {
// 存储用户输入
userName := answer
// 返回下一个提示
return &strumt.BaseLinePrompter{
PromptString: fmt.Sprintf("你好 %s! 请输入您的年龄: ", userName),
Validator: func(input string) error {
if input == "" {
return fmt.Errorf("年龄不能为空")
}
return nil
},
Next: func(answer string) strumt.Prompter {
fmt.Printf("感谢您的输入,%s (%s岁)!\n", userName, answer)
return nil // 返回nil结束流程
},
}
},
})
p.Run()
}
更复杂的示例
下面是一个更复杂的示例,模拟一个用户注册流程:
package main
import (
"fmt"
"os"
"strings"
"github.com/antham/strumt"
)
func main() {
p := strumt.NewPromptsFromReaderAndWriter(os.Stdin, os.Stdout)
// 用户数据存储
var user struct {
Username string
Email string
Password string
Plan string
}
// 用户名提示
p.AddLinePrompter(&strumt.BaseLinePrompter{
PromptString: "请输入用户名: ",
Validator: func(input string) error {
if len(input) < 3 {
return fmt.Errorf("用户名至少需要3个字符")
}
return nil
},
Next: func(answer string) strumt.Prompter {
user.Username = answer
return &strumt.BaseLinePrompter{
PromptString: "请输入邮箱地址: ",
Validator: func(input string) error {
if !strings.Contains(input, "@") {
return fmt.Errorf("请输入有效的邮箱地址")
}
return nil
},
Next: func(answer string) strumt.Prompter {
user.Email = answer
return &strumt.BaseLinePrompter{
PromptString: "请输入密码: ",
MaskInput: true, // 隐藏输入
Validator: func(input string) error {
if len(input) < 6 {
return fmt.Errorf("密码至少需要6个字符")
}
return nil
},
Next: func(answer string) strumt.Prompter {
user.Password = answer
return &strumt.BaseLinePrompter{
PromptString: "请选择套餐 (basic/premium/vip): ",
Validator: func(input string) error {
switch input {
case "basic", "premium", "vip":
return nil
default:
return fmt.Errorf("无效的套餐选择")
}
},
Next: func(answer string) strumt.Prompter {
user.Plan = answer
// 确认步骤
return &strumt.BaseLinePrompter{
PromptString: fmt.Sprintf(
"确认注册信息:\n用户名: %s\n邮箱: %s\n套餐: %s\n确认? (y/n): ",
user.Username, user.Email, user.Plan,
),
Validator: func(input string) error {
if input != "y" && input != "n" {
return fmt.Errorf("请输入 y 或 n")
}
return nil
},
Next: func(answer string) strumt.Prompter {
if answer == "y" {
fmt.Println("注册成功!")
// 这里可以添加实际注册逻辑
} else {
fmt.Println("注册已取消")
}
return nil // 结束流程
},
}
},
}
},
}
},
}
},
})
p.Run()
}
高级功能
多选提示
p.AddLinePrompter(&strumt.BaseLinePrompter{
PromptString: "选择您感兴趣的主题 (多个选项用逗号分隔):\n1. Go\n2. Python\n3. Rust\n4. JavaScript\n",
Validator: func(input string) error {
if input == "" {
return fmt.Errorf("请至少选择一个主题")
}
return nil
},
Next: func(answer string) strumt.Prompter {
topics := strings.Split(answer, ",")
fmt.Printf("您选择了: %v\n", topics)
return nil
},
})
默认值和帮助信息
p.AddLinePrompter(&strumt.BaseLinePrompter{
PromptString: "请输入服务器端口 [默认: 8080]: ",
Default: "8080",
Help: "这是服务器监听的端口号",
Validator: func(input string) error {
if input == "" {
return nil // 使用默认值
}
// 验证端口号
return nil
},
Next: func(answer string) strumt.Prompter {
if answer == "" {
answer = "8080"
}
fmt.Printf("将使用端口: %s\n", answer)
return nil
},
})
最佳实践
- 清晰的提示信息:确保每个提示都清楚地说明需要输入什么
- 输入验证:对每个输入进行验证,提供有用的错误信息
- 模块化设计:将复杂的提示链分解为多个函数
- 提供默认值:在适当的地方提供默认值简化用户输入
- 添加帮助信息:为复杂提示添加帮助信息
strumt 是一个强大而灵活的工具,可以帮助你构建复杂的交互式命令行界面。通过合理设计提示链,你可以创建出用户体验良好的 CLI 工具。