跳到主要内容

打造命令行工具

打造命令行工具 引言

常规来讲,命令行工具对于一个框架是蛮有用的,将很多重复性的工作提取到命令行,执行命令,比如生成Model,生成控制器,生成路由等等 go标准库flag是用来解析命令行参数的包 不过我们选择cobra来构建我们的命令行工具,非常多知名的开源项目使用了 cobra 库构建命令行,如Kubernetes、Hugo、etcd等等等等。 案例代码地址 初始化

  1. 安装cobra工具 go get github.com/spf13/cobra

    通常会安装到gopath目录下的bin目录

复制代码 2. 初始化 cobra init --pkg-name=mycmd 复制代码 会新建一个mycmd目录

▾ mycmd/ ▾ cmd/ root.go main.go 复制代码 3. 添加一个emial子命令 cobra add email 复制代码 2.特性

  1. 基本概念 命令(Command):就是需要执行的操作; 参数(Arg):命令的参数,即要操作的对象; 选项(Flag):命令选项可以调整命令的行为
  2. 命令 在 cobra 中,命令和子命令都是用Command结构表示的。Command有非常多的字段,用来定制命令的行为。 在实际中,最常用的就那么几个。

Use 指定使用信息,即命令怎么被调用,格式为name arg1 [arg2]。name为命令名,后面的arg1为必填参数,arg3为可选参数,参数可以多个。 Short 简短描述 Long 长描述 Run 实际执行的函数 Example 使用案例 3. 选项 cobra 使用pflag解析命令行选项。pflag使用上基本与flag相同

全局选项 定义它的命令和其子命令都可以使用

rootCmd.PersistentFlags().StringVar(&cfgFile, "config", cfgFile, "config file (default is $HOME/.mycmd.toml)") 复制代码 局部选项 只能定义的字命令使用

localCmd.Flags().StringVarP(&Source, "source", "s", "", "Source directory to read from") 复制代码 3、完善email子命令

package cmd

import (
"fmt"
"log"
"net/smtp"

"github.com/jordan-wright/email"
"github.com/spf13/cobra"
"github.com/spf13/viper"
)

var (
To []string
Cc []string
Bcc []string
//主题
Subject string
//内容
Text string
//html内容(优先)
HTML string
//抄送附件
AttachFileName string
From string
Smtp string
Port int
Password string
)

// emailCmd represents the email command
var emailCmd = &cobra.Command{
Use: "email",
Short: "发送邮件",
Long: `为了更便捷的发送邮件`,
Example: `
基础发送:mycmd email -c "内容" -t "youremail"
抄送:mycmd email -c "签到" -t "youremail" --cc "yourccemail"
私密抄送:mycmd email -c "签到" -t "youremail" --bcc "yourcccemail"
发送html:mycmd email -c "签到" -t "youremail" --html='<a href="http://www.baidu.com">点击</a>'
发送附件:mycmd email -c "签到" -t "youremail" --file="./cmd.toml.example"
`,
Run: func(cmd *cobra.Command, args []string) {
send()
},
}

func init() {
emailCmd.Flags().StringSliceVarP(&To, "to", "t", []string{}, "send email to")
emailCmd.Flags().StringSliceVar(&Cc, "cc", []string{}, "send email Cc")
emailCmd.Flags().StringSliceVar(&Bcc, "bcc", []string{}, "send email Bcc")
emailCmd.Flags().StringVarP(&Subject, "subject", "s", "默认主题", "send email Subject")
emailCmd.Flags().StringVarP(&Text, "context", "c", "", "send email Text")
emailCmd.Flags().StringVar(&HTML, "html", "", "send email HTML contect")
emailCmd.Flags().StringVar(&AttachFileName, "file", "", "send email AttachFile")
emailCmd.MarkFlagRequired("to")
emailCmd.MarkFlagRequired("context")
rootCmd.AddCommand(emailCmd)

// Here you will define your flags and configuration settings.

// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
// emailCmd.PersistentFlags().String("foo", "", "A help for foo")

// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// emailCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}

func send() {
From = viper.GetString("email.from")
Smtp = viper.GetString("email.smtp")
Port = viper.GetInt("email.port")
Password = viper.GetString("email.password")

e := email.NewEmail()
e.From = From
e.To = To
e.Cc = Cc
e.Bcc = Bcc
e.Subject = Subject
e.AttachFile(AttachFileName)
if HTML != "" {
e.HTML = []byte(HTML)
} else {
e.Text = []byte(Text)
}
auth := smtp.PlainAuth("", From, Password, Smtp)
addr := fmt.Sprintf("%s:%d", Smtp, Port)
err := e.Send(addr, auth)
if err != nil {
log.Fatal("email ", err)
}

log.Println("发送成功")
}

复制代码 4、测试命令 1、编译程序 go build . 2、按照示例执行 ./mycmd email -c "内容" -t "baichonghua@urthink.com" 复制代码 5、其它 验证选项必填使用 MarkFlagRequired cobra 还提供了非常丰富的特性和定制化接口,例如:设置钩子函数,在命令执行前、后执行某些操作;生成 Markdown/ReStructed Text/Man Page 格式的文档等等,有需要的朋友自行研究