Cobra для Go: полное руководство с примерами

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение в Cobra: что это и зачем нужно

Cobra — это мощная библиотека для языка программирования Go, предназначенная для создания современных интерфейсов командной строки (CLI). Она предоставляет простой и интуитивно понятный API для построения сложных приложений с поддержкой вложенных команд, флагов, аргументов и автоматической генерации справки.

Зачем нужна Cobra? В современной разработке CLI-инструменты играют ключевую роль: от утилит DevOps до повседневных инструментов разработчика. Cobra решает несколько критических задач:

  • Структурирование команд: позволяет создавать иерархию команд (например, app server start, app config set).
  • Автоматическая справка: генерирует документацию на основе ваших команд и флагов.
  • Гибкая обработка аргументов: поддерживает позиционные аргументы, обязательные и опциональные флаги.
  • Интеграция с Viper: легко комбинируется с библиотекой Viper для управления конфигурацией.
  • Скорость разработки: благодаря генератору кода cobra-cli можно создать каркас приложения за секунды.

Cobra используется в таких известных проектах, как Kubernetes, Hugo, Docker (частично), GitHub CLI и многих других.

Установка Cobra

Установка Cobra в проект на Go выполняется стандартным способом через модули Go. Убедитесь, что у вас установлен Go версии 1.16 или выше.

# Инициализация модуля (если ещё не сделано)
go mod init mycli

# Установка Cobra
go get -u github.com/spf13/cobra@latest

# Установка генератора cobra-cli (опционально, но рекомендуется)
go install github.com/spf13/cobra-cli@latest

После установки вы можете проверить версию Cobra в вашем go.mod файле. Генератор cobra-cli создаст базовую структуру проекта с правильной конфигурацией.

Быстрый старт с Cobra

Создадим простое CLI-приложение, которое выводит приветствие. Сначала инициализируем проект с помощью cobra-cli:

cobra-cli init myapp
cd myapp

Эта команда создаст структуру файлов: main.go, cmd/root.go. Теперь добавим команду hello:

cobra-cli add hello

После этого отредактируем файл cmd/hello.go:

package cmd

import (
    "fmt"
    "github.com/spf13/cobra"
)

func init() {
    rootCmd.AddCommand(helloCmd)
}

var helloCmd = &cobra.Command{
    Use:   "hello",
    Short: "Выводит приветствие",
    Long:  `Команда hello выводит персонализированное приветствие пользователю.`,
    Run: func(cmd *cobra.Command, args []string) {
        name, _ := cmd.Flags().GetString("name")
        if name == "" {
            name = "World"
        }
        fmt.Printf("Hello, %s!\n", name)
    },
}

func init() {
    helloCmd.Flags().StringP("name", "n", "", "Имя для приветствия")
}

Теперь запустите приложение:

go run main.go hello --name "Alice"
# Вывод: Hello, Alice!

go run main.go hello
# Вывод: Hello, World!

Основные методы и функции Cobra

1. cobra.Command — создание команды

Что делает: Определяет новую команду в CLI-приложении. Это основной строительный блок Cobra.

Параметры:

  • Use — имя команды и шаблон использования (например, "hello [name]")
  • Short — краткое описание (отображается в списке команд)
  • Long — подробное описание (отображается в справке)
  • Run — функция, выполняемая при вызове команды
  • Args — валидатор аргументов (например, cobra.ExactArgs(2))
var versionCmd = &cobra.Command{
    Use:   "version",
    Short: "Показывает версию приложения",
    Long:  `Выводит текущую версию приложения и информацию о сборке.`,
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("MyCLI v1.0.0")
    },
}

func init() {
    rootCmd.AddCommand(versionCmd)
}

2. AddCommand() — добавление подкоманды

Что делает: Регистрирует дочернюю команду для родительской команды. Позволяет строить иерархию команд.

Параметры: Один или несколько указателей на cobra.Command.

var configCmd = &cobra.Command{
    Use:   "config",
    Short: "Управление конфигурацией",
}

var configSetCmd = &cobra.Command{
    Use:   "set",
    Short: "Устанавливает параметр конфигурации",
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Config set command executed")
    },
}

func init() {
    rootCmd.AddCommand(configCmd)
    configCmd.AddCommand(configSetCmd)
}

3. Flags().StringP() — добавление строкового флага

Что делает: Добавляет флаг строкового типа с короткой и длинной формой.

Параметры:

  • name — длинное имя флага (например, "username")
  • shorthand — короткое имя (одна буква, например "u")
  • value — значение по умолчанию
  • usage — описание флага для справки
var greetCmd = &cobra.Command{
    Use: "greet",
    Run: func(cmd *cobra.Command, args []string) {
        name, _ := cmd.Flags().GetString("username")
        fmt.Printf("Greetings, %s!\n", name)
    },
}

func init() {
    greetCmd.Flags().StringP("username", "u", "Guest", "Имя пользователя")
    rootCmd.AddCommand(greetCmd)
}

4. Flags().IntP() — добавление целочисленного флага

Что делает: Добавляет флаг целочисленного типа.

Параметры: Аналогичны StringP, но value — целое число.

var calcCmd = &cobra.Command{
    Use: "calc",
    Run: func(cmd *cobra.Command, args []string) {
        a, _ := cmd.Flags().GetInt("a")
        b, _ := cmd.Flags().GetInt("b")
        fmt.Printf("Sum: %d\n", a+b)
    },
}

func init() {
    calcCmd.Flags().IntP("a", "a", 0, "Первое число")
    calcCmd.Flags().IntP("b", "b", 0, "Второе число")
    rootCmd.AddCommand(calcCmd)
}

5. Flags().BoolP() — добавление булевого флага

Что делает: Добавляет флаг-переключатель (true/false).

Параметры: Аналогичны, но value — bool.

var verboseCmd = &cobra.Command{
    Use: "process",
    Run: func(cmd *cobra.Command, args []string) {
        verbose, _ := cmd.Flags().GetBool("verbose")
        if verbose {
            fmt.Println("Verbose mode enabled")
        }
        fmt.Println("Processing...")
    },
}

func init() {
    verboseCmd.Flags().BoolP("verbose", "v", false, "Подробный вывод")
    rootCmd.AddCommand(verboseCmd)
}

6. MarkFlagRequired() — обязательный флаг

Что делает: Помечает флаг как обязательный. Если флаг не указан, Cobra выдаст ошибку.

Параметры: Имя флага (строка).

var loginCmd = &cobra.Command{
    Use: "login",
    Run: func(cmd *cobra.Command, args []string) {
        username, _ := cmd.Flags().GetString("username")
        password, _ := cmd.Flags().GetString("password")
        fmt.Printf("Logging in as %s\n", username)
    },
}

func init() {
    loginCmd.Flags().StringP("username", "u", "", "Имя пользователя")
    loginCmd.Flags().StringP("password", "p", "", "Пароль")
    loginCmd.MarkFlagRequired("username")
    loginCmd.MarkFlagRequired("password")
    rootCmd.AddCommand(loginCmd)
}

7. Args — валидация аргументов

Что делает: Определяет правила проверки позиционных аргументов команды.

Параметры: Функция-валидатор (например, cobra.ExactArgs(2), cobra.MinimumNArgs(1), cobra.RangeArgs(1, 3)).

var copyCmd = &cobra.Command{
    Use:   "copy [source] [destination]",
    Short: "Копирует файл",
    Args:  cobra.ExactArgs(2),
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Printf("Copying from %s to %s\n", args[0], args[1])
    },
}

func init() {
    rootCmd.AddCommand(copyCmd)
}

8. PersistentPreRunE — перехватчик выполнения

Что делает: Выполняет функцию перед запуском команды. Позволяет реализовать общую логику (аутентификация, инициализация) для всех подкоманд.

Параметры: Функция с сигнатурой func(cmd *cobra.Command, args []string) error.

var apiCmd = &cobra.Command{
    Use: "api",
    PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
        token, _ := cmd.Flags().GetString("token")
        if token == "" {
            return fmt.Errorf("требуется токен аутентификации")
        }
        fmt.Println("Аутентификация пройдена")
        return nil
    },
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("API command executed")
    },
}

func init() {
    apiCmd.Flags().StringP("token", "t", "", "API токен")
    rootCmd.AddCommand(apiCmd)
}

9. HelpFunc() — кастомизация справки

Что делает: Позволяет переопределить стандартную функцию вывода справки для команды.

Параметры: Функция с сигнатурой func(*Command, []string).

var customHelpCmd = &cobra.Command{
    Use: "custom",
    HelpFunc: func(cmd *cobra.Command, args []string) {
        fmt.Println("=== Моя кастомная справка ===")
        fmt.Println("Использование:", cmd.Use)
        fmt.Println("Описание:", cmd.Short)
    },
    Run: func(cmd *cobra.Command, args []string) {
        fmt.Println("Custom command")
    },
}

func init() {
    rootCmd.AddCommand(customHelpCmd)
}

10. SetVersionTemplate() — шаблон версии

Что делает: Устанавливает шаблон для вывода версии приложения.

Параметры: Строка с шаблоном (используется синтаксис Go templates).

func init() {
    rootCmd.SetVersionTemplate(`{{printf "MyCLI version: %s\n" .Version}}`)
    rootCmd.Version = "2.0.0"
}

// Использование: go run main.go --version

Реальный практический пример: утилита для работы с задачами

Создадим полноценное CLI-приложение для управления списком задач (task manager). Приложение будет поддерживать команды: add, list, complete,

Рекомендаций