零、前言
本次教程使用的開(kāi)源框架如下:
名字 | 開(kāi)源地址 | 作用 |
---|---|---|
Cobra | 命令行工具 | https://github.com/spf13/cobra |
Aurora | 字體顏色 | https://github.com/logrusorgru/aurora |
go-zero | go-z框架 模板功能 | https://github.com/zeromicro/go-zero |
本項(xiàng)目完整源碼:https://github.com/ctra-wang/cobra-gen-drone
一、初識(shí) Cobra
1、Cobra作用
概述:Cobra 是一個(gè) Golang 包,它提供了簡(jiǎn)單的接口來(lái)創(chuàng)建命令行程序。同時(shí),Cobra 也是一個(gè)應(yīng)用程序,用來(lái)生成應(yīng)用框架,從而開(kāi)發(fā)以 Cobra 為基礎(chǔ)的應(yīng)用。
代表作:docker
、k8s
、helm
等
詳細(xì)使用就不在這里詳細(xì)介紹了
- 推薦文章如下:
官方文檔:https://cobra.dev/
Go 語(yǔ)言現(xiàn)代命令行框架 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格式結(jié)尾的文件)
通過(guò)渲染模板,才能輸出我們想要的最終文件
1、go template 使用
詳細(xì)使用和說(shuō)明接不介紹了
- 推薦文章如下:
go template使用:https://blog.csdn.net/skh2015java/article/details/126213329
關(guān)于template:
我們可以使用 .tpl的文件,也可以直接用 ``字符串包裹進(jìn)行渲染。主要使用go中 {{}} 雙大括號(hào)的特性
三、開(kāi)始項(xiàng)目
整個(gè)項(xiàng)目目錄如下:
1、創(chuàng)建項(xiàng)目整理目錄
1.1、創(chuàng)建go.mod 和 cmd文件夾
go mod init xxxx
mkdir cmd
1.2、創(chuàng)建main文件
package main
import (
"app/cmd"
)
func main() {
cmd.Execute()
}
1.3、在cmd文件夾創(chuàng)建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: `創(chuàng)建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文件夾創(chuàng)建 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 {
// 步驟四
// 對(duì)所有的傳入的參數(shù)進(jìn)行一一判斷
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("文件創(chuàng)建失敗:", err)
return err
} else {
fmt.Println("文件創(chuàng)建成功!")
}
defer file.Close()
text, err := pathx.LoadTemplate("dronegen", "drone.tpl", UsageTpl)
if err != nil {
fmt.Println("打開(kāi)模板失敗:", err)
return err
} else {
fmt.Println("打開(kāi)模板成功!")
}
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、創(chuàng)建 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中如何調(diào)試?
這種命令行的代碼調(diào)試和傳統(tǒng)的main入口程序調(diào)試是完全不一樣的
2.1、Edit configurations
配置這里
2.2、program argument
這里很重要,如果這里不設(shè)置我們需要輸入的指令值,則無(wú)法進(jìn)入對(duì)應(yīng)的斷點(diǎn)
3、編譯執(zhí)行
3.1、將文件編譯成二進(jìn)制文件
go build main.go
3.2、執(zhí)行
長(zhǎng)指令
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 文件已經(jīng)生成
4、注意這里踩得大坑
來(lái)看一下在 Drone 的配置頁(yè)面中
Configuration 默認(rèn)的文件名的前綴 是點(diǎn)!?。?/code>
Golang中的
os.create()
函數(shù)文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-600714.html
file, err := os.Create("drone.yml")
if err != nil {
fmt.Println("文件創(chuàng)建失敗:", err)
return err
} else {
fmt.Println("文件創(chuàng)建成功!")
}
如果我們使用默認(rèn)的
.drone.yml
,則我們將編譯好的文件在哪執(zhí)行都不會(huì)產(chǎn)生這個(gè)文件?。∈种?span toymoban-style="hidden">文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-600714.html
file, err := os.Create(".drone.yml")
到了這里,關(guān)于【cobra】手寫(xiě)你的第一個(gè)命令行腳手架工具 | cobra整合go template通過(guò)終端以命令行方式生成.drone.yml 模板的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!