Cero Prólogo
El marco de código abierto utilizado en este tutorial es el siguiente:
nombre | dirección de fuente abierta | efecto |
---|---|---|
Cobra | herramienta de línea de comandos | https://github.com/spf13/cobra |
Aurora | color de fuente | https://github.com/logrusorgru/aurora |
ir a cero | función de plantilla de marco go-z | https://github.com/zeromicro/go-zero |
El código fuente completo de este proyecto : https://github.com/ctra-wang/cobra-gen-drone
1. Conociendo a Cobra por primera vez
1. El papel de Cobra
Descripción general : Cobra es un paquete de Golang que proporciona una interfaz simple para crear programas de línea de comandos. Al mismo tiempo, Cobra también es un programa de aplicación, que se utiliza para generar un marco de aplicación para desarrollar aplicaciones basadas en Cobra.
Obras representativas :docker
,k8s
,helm
etc.
El uso detallado no se introducirá en detalle aquí.
- Los artículos recomendados son los siguientes:
Documentación oficial: https://cobra.dev/
- Los videos recomendados son los siguientes:
二、ir plantilla
Aquí está la plantilla que queremos renderizar (el archivo que termina en formato .tpl)
.Al renderizar la plantilla, podemos generar el archivo final que queremos
1. ir a usar la plantilla
El uso detallado y las instrucciones no se introducirán
- Los artículos recomendados son los siguientes:
Uso de la plantilla Go: https://blog.csdn.net/skh2015java/article/details/126213329
Con respecto a la plantilla :
podemos usar archivos .tpl o envolverlos directamente con `` cadenas para renderizar. Utilice principalmente las características de { {}} llaves dobles en go
3. Iniciar el proyecto
El directorio completo del proyecto es el siguiente:
1. Crea un catálogo de proyectos
1.1 Crear carpetas go.mod y cmd
go mod init xxxx
mkdir cmd
1.2, crea el archivo principal
package main
import (
"app/cmd"
)
func main() {
cmd.Execute()
}
1.3 Crear cmd.go en la carpeta cmd
el código se muestra a continuación
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 Crear drone.go en la carpeta cmd
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 Crear archivo de plantilla 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. ¿Cómo depurar en goland?
Este tipo de depuración de código de línea de comando es completamente diferente de la depuración tradicional del programa de entrada principal.
2.1、Editar configuraciones
configurar aquí
2.2, argumento del programa
Esto es muy importante, si el valor de instrucción que necesitamos ingresar no se establece aquí, no se puede ingresar el punto de interrupción correspondiente
3. Compilar y ejecutar
3.1, compile el archivo en un archivo binario
go build main.go
3.2 Ejecución
comando largo
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"
comando corto
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"
Puedes ver que se ha generado el archivo drone.yml
4. Presta atención al gran hoyo aquí
Eche un vistazo a la página de configuración de Drone.
El prefijo de nombre de archivo predeterminado de Configuración es点!!!
os.create()
Funciones en Golang
file, err := os.Create("drone.yml")
if err != nil {
fmt.Println("文件创建失败:", err)
return err
} else {
fmt.Println("文件创建成功!")
}
Si usamos el predeterminado
.drone.yml
, ¡no generaremos este archivo dondequiera que ejecutemos el archivo compilado! ! Pozo de diez
file, err := os.Create(".drone.yml")