零、前言
本次教程使用的开源框架如下:
名字 | 开源地址 | 作用 |
---|---|---|
Cobra | 命令行工具 | https://github.com/spf13/cobra |
Aurora | 字体颜色 | https://github.com/logrusorgru/aurora |
go-zero | go-z框架 模板功能 | https://github.com/zeromicro/go-zero |
本项目完整源码:https://github.com/ctra-wang/cobra-gen-drone
一、初识 Cobra
1、Cobra作用
概述:Cobra 是一个 Golang 包,它提供了简单的接口来创建命令行程序。同时,Cobra 也是一个应用程序,用来生成应用框架,从而开发以 Cobra 为基础的应用。
代表作:docker
、k8s
、helm
等
详细使用就不在这里详细介绍了
- 推荐文章如下:
官方文档:https://cobra.dev/
Go 语言现代命令行框架 Cobra 详解:https://jianghushinian.cn/2023/05/08/go-modern-command-line-framework-cobra-details/
Cobra 快速入门 - 专为命令行程序而生:https://blog.csdn.net/xcbeyond/article/details/119429114
- 推荐视频如下:
cobra的基本使用
二、go template
这里是我们要渲染模板(.tpl格式结尾的文件)
通过渲染模板,才能输出我们想要的最终文件
1、go template 使用
详细使用和说明接不介绍了
- 推荐文章如下:
go template使用:https://blog.csdn.net/skh2015java/article/details/126213329
关于template:
我们可以使用 .tpl的文件,也可以直接用 ``字符串包裹进行渲染。主要使用go中 {{}} 双大括号的特性
三、开始项目
整个项目目录如下:
1、创建项目整理目录
1.1、创建go.mod 和 cmd文件夹
go mod init xxxx
mkdir cmd
1.2、创建main文件
package main
import (
"app/cmd"
)
func main() {
cmd.Execute()
}
1.3、在cmd文件夹创建cmd.go
代码如下
package cmd
import (
"fmt"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"os"
)
// droneCmd represents the drone command
var droneCmd = &cobra.Command{
Use: "drone",
Short: "drone is very good",
Long: `创建drone的指令`,
RunE: DroneGenerator, //步骤一
}
var (
//步骤三
DroneName string
GoPrivate string
ServiceName string
ServiceType string
GitBranch string
Registry string
Repo string
Tag string
)
func Execute() {
if err := droneCmd.Execute(); err != nil {
fmt.Println(aurora.Red(err.Error()))
os.Exit(1)
}
}
func init() {
// drone --droneName="base" --go_private="gitee.com" --service_name="baserpc.go" --service_type="rpc" --gitBranch="master" --registry="registry.cn-beijing.aliyuncs.com" --repo="registry.cn-beijing.aliyuncs.com/ctra_test/ctra-go-zhiye-rpc" --tag="latest"
// drone -d="base" -g="gitee.com" -s="baserpc.go" -x="rpc" -b="master" -r="registry.cn-beijing.aliyuncs.com" -o="registry.cn-beijing.aliyuncs.com/ctra_test/ctra-go-zhiye-rpc" -t="latest"
// 步骤二
droneCmd.Flags().StringVarP(&DroneName, aurora.Yellow("droneName").String(), "d", "", aurora.Green(`The Drone name`).String())
droneCmd.Flags().StringVarP(&GoPrivate, "go_private", "g", "", aurora.Green(`Go private (default "gitee.com")`).String())
droneCmd.Flags().StringVarP(&ServiceName, "service_name", "s", "", aurora.Green(`The service name of the project`).String())
droneCmd.Flags().StringVarP(&ServiceType, "service_type", "x", "", aurora.Green(`The service type, such as rpc | api`).String())
droneCmd.Flags().StringVarP(&GitBranch, "gitBranch", "b", "", `The branch of the remote repo, it does work with --remote (default "master")`)
droneCmd.Flags().StringVarP(&Registry, "registry", "r", "", `The remote git repo of the template, --home and --remote cannot be set at the same time, if they are, --remote has higher priority
The git repo directory must be consistent with the https://github.com/zeromicro/go-zero-template directory structure`)
droneCmd.Flags().StringVarP(&Repo, "repo", "o", "", aurora.Green(`The project git repository`).String())
droneCmd.Flags().StringVarP(&Tag, "tag", "t", "", aurora.Green("Git tag (default \"latest\")").String())
// Here you will define your flags and configuration settings.
// Cobra supports Persistent Flags which will work for this command
// and all subcommands, e.g.:
droneCmd.PersistentFlags().String("droneName", "", "A help for foo")
// Cobra supports local flags which will only run when this command
// is called directly, e.g.:
// droneCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle")
}
1.4、在cmd文件夹创建 drone.go
package cmd
import (
_ "embed"
"fmt"
"github.com/logrusorgru/aurora"
"github.com/spf13/cobra"
"github.com/zeromicro/go-zero/tools/goctl/util/pathx"
"os"
"strings"
"text/template"
)
var (
//go:embed drone.tpl
UsageTpl string
)
type Drone struct {
//步骤三
DroneName string
GoPrivate string
ServiceName string
ServiceType string
GitBranch string
Registry string
Repo string
Tag string
}
func DroneGenerator(_ *cobra.Command, _ []string) error {
// 步骤四
// 对所有的传入的参数进行一一判断
dronename := DroneName
if len(dronename) == 0 {
dronename = "dronegen-greet"
}
goprivate := GoPrivate
fmt.Println(len(strings.Split(goprivate, ".")))
if len(strings.Split(goprivate, ".")) <= 1 {
return fmt.Errorf("error go private!")
}
serviceName := ServiceName
serviceType := ServiceType
gitBranch := GitBranch
registry := Registry
repo := Repo
tag := Tag
file, err := os.Create("drone.yml")
if err != nil {
fmt.Println("文件创建失败:", err)
return err
} else {
fmt.Println("文件创建成功!")
}
defer file.Close()
text, err := pathx.LoadTemplate("dronegen", "drone.tpl", UsageTpl)
if err != nil {
fmt.Println("打开模板失败:", err)
return err
} else {
fmt.Println("打开模板成功!")
}
t := template.Must(template.New("dronegen").Parse(text))
return t.Execute(file, Drone{
DroneName: dronename,
GoPrivate: goprivate,
ServiceName: serviceName,
ServiceType: serviceType,
GitBranch: gitBranch,
Registry: registry,
Repo: repo,
Tag: tag,
})
fmt.Println(aurora.Green("Done."))
return nil
}
1.5、创建 drone.tpl 模板文件
kind: pipeline
type: docker
name: {{.DroneName}}-{{.ServiceType}}
steps:
- name: build-go
image: golang:1.20.3
depends_on: [clone]
volumes:
- name: go_cache
path: /go/pkg/mod
commands:
- go env -w CGO_ENABLED=0
- go env -w GOPROXY=https://goproxy.cn,direct
- go env -w GOPRIVATE= {{.GoPrivate}}
- go mod tidy && go build -trimpath -ldflags "-s -w" -o app {{.ServiceName}}.go
- name: build-{{.ServiceType}}
image: plugins/docker:20
environment:
DRONE_REPO_BRANCH: {{.GitBranch}}
depends_on: [build-go]
settings:
dockerfile: Dockerfile
registry: {{.Registry}}
repo: {{.Repo}}:{{.Tag}}
auto_tag: true
insecure: true
username:
from_secret: docker_username
password:
from_secret: docker_password
trigger:
ref:
- refs/tags/*
- refs/heads/master
volumes:
- name: go_cache
host:
path: /root/.go/cache
2、goland中如何调试?
这种命令行的代码调试和传统的main入口程序调试是完全不一样的
2.1、Edit configurations
配置这里
2.2、program argument
这里很重要,如果这里不设置我们需要输入的指令值,则无法进入对应的断点
3、编译执行
3.1、将文件编译成二进制文件
go build main.go
3.2、执行
长指令
drone -d="base" -g="gitee.com" -s="baserpc.go" -x="rpc" -b="master" -r="registry.cn-beijing.aliyuncs.com" -o="registry.cn-beijing.aliyuncs.com/ctra_test/ctra-go-zhiye-rpc" -t="latest"
短指令
drone --droneName="base" --go_private="gitee.com" --service_name="baserpc.go" --service_type="rpc" --gitBranch="master" --registry="registry.cn-beijing.aliyuncs.com" --repo="registry.cn-beijing.aliyuncs.com/ctra_test/ctra-go-zhiye-rpc" --tag="latest"
可以看到drone.yml 文件已经生成
4、注意这里踩得大坑
来看一下在 Drone 的配置页面中
Configuration 默认的文件名的前缀 是点!!!
Golang中的
os.create()
函数文章来源:https://www.toymoban.com/news/detail-600714.html
file, err := os.Create("drone.yml")
if err != nil {
fmt.Println("文件创建失败:", err)
return err
} else {
fmt.Println("文件创建成功!")
}
如果我们使用默认的
.drone.yml
,则我们将编译好的文件在哪执行都不会产生这个文件!!十分之坑文章来源地址https://www.toymoban.com/news/detail-600714.html
file, err := os.Create(".drone.yml")
到了这里,关于【cobra】手写你的第一个命令行脚手架工具 | cobra整合go template通过终端以命令行方式生成.drone.yml 模板的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!