[cobra] Escriba a mano su primera herramienta de andamiaje de línea de comandos | cobra integra la plantilla go para generar una plantilla .drone.yml a través de la línea de comandos a través de la terminal

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

inserte la descripción de la imagen aquí

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, helmetc.

El uso detallado no se introducirá en detalle aquí.

  • Los artículos recomendados son los siguientes:

Documentación oficial: https://cobra.dev/

Explicación detallada de Cobra, un marco de línea de comando moderno para el lenguaje Go: https://jianghushinian.cn/2023/05/08/go-modern-command-line-framework-cobra-details/

Cobra Quick Start: diseñado para programas de línea de comandos: https://blog.csdn.net/xcbeyond/article/details/119429114

  • Los videos recomendados son los siguientes:

Uso básico de cobra

二、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

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:
inserte la descripción de la imagen aquí

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í
inserte la descripción de la imagen 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

inserte la descripción de la imagen aquí

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
inserte la descripción de la imagen aquí

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点!!!

inserte la descripción de la imagen aquí

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")

Supongo que te gusta

Origin blog.csdn.net/wanglei19891210/article/details/131847587
Recomendado
Clasificación