大家好, 我是老麦, 我将每天 早上9点 为你分享一篇好文章。

原文链接: https://tangx.in/posts/2023/01/26/devopscamp-cobra-interactive-survey/

本文为 DevOpsCamp 实战训练作业 cobra - 03 配置文件的读取与写入(简单) 的解题答案

DevoOpsCamp 作业地址:https://www.devopscamp.cc/semi-plan-202301-2/posts/homework/cobra03/

要求:

  1. 使用 https://github.com/spf13/cobra 实现命令工具
  2. 使用 https://github.com/go-survey/survey 实现交互式命令
  3. 实现 Demo 效果
aliyun
aliyun configure --profile

解题过程

survey
go modulesurvey
go module version
https://github.com/go-survey/survey
$ go get -u github.com/AlecAivazis/survey/v2
go.mod
module github.com/AlecAivazis/survey/v2
Usageexmaple_test.go

2. 需要使用的交互组件

surveyOption
InputPassword*SelectMultiSelectConfirm

更多其它组件, 可以参考官方文档。

3. 代码片段

参考 aliyun 命令行, 我们自己实现的功能需要以下字段。

  1. Access Secret ID
  2. Access Secret Key
  3. Region
  4. Language
answers
 answers := struct {
  ID          string
  Key         string
  ChinaRegion string `survey:"region"`
  Language    []string
 }{}
ChinaRegionsurvey:"region"regionjson, yaml

另一方面, 我们还准备了一系列问题, 引导用户输入

// the questions to ask
var qs = []*survey.Question{
 {
  // 1. Input 输入框
  Name: "id",
  Prompt: &survey.Input{
   Message: "Access Secret ID: ",
  },
  Validate: survey.Required,
 },
 {
  // 2. Password 密码输入框
  Name: "key",
  Prompt: &survey.Password{
   Message: "Access Secret Key: ",
  },
  Validate: survey.Required,
 },
 {
  // 3. Select 单选框
  Name: "region",
  Prompt: &survey.Select{
   Message: "Choose a region:",
   Options: []string{"cn-shanghai", "cn-hangzhou"},
   Default: "cn-hangzhou",
  },
 },
 {
  // 4. MultiSelect 多选框
  Name: "language",
  Prompt: &survey.MultiSelect{
   Message: "Supported Configure Language: ",
   Options: []string{"zh", "en", "jp"},
  },
 },
}
qsNameanswersidkeyregioncn-hangzhou
Confirmconfirm
func confirm() bool {
 ok := false
 // 5. Confirm 确认框
 prompt := &survey.Confirm{
  Message: "是否保存文件?",
 }
 survey.AskOne(prompt, &ok)

 return ok
}
JSON MashralIndent
MarshalIndent
{
  "ID": "AKID-demodemo-adsfasdf",
  "Key": "flasjdflaksdjf",
  "ChinaRegion": "cn-shanghai",
  "Language": [
    "zh",
    "en"
  ]
}
profile
main
var profile string
profile
dumpConfig全局的profile

关于 目录结构 我们将会在后面的作业中提到。

var root = &cobra.Command{
 Use:   "aliyunx",
 Short: "aliyun 配置中心",
 Run: func(cmd *cobra.Command, args []string) {
  // 1. 使用全局 profile
  interactive(profile)
 },
}

func interactive(profile string) {
 // 2. 参数传递
 dumpConfig(profile, answers)
}

func dumpConfig(profile string, answer any) {
 // 3. 参数传递
 name := fmt.Sprintf("%s.config.json", profile)
 err2 := os.WriteFile(name, b, os.ModePerm)
 if err2 != nil {
  panic(err2)
 }
}

效果展示

关联文章