No description
Find a file
2026-03-20 11:22:00 +03:00
docs Добавление глобальной переменной окружения CONFIG_FILE 2026-03-20 11:21:19 +03:00
examples Примеры использования 2026-03-19 16:33:25 +03:00
.gitignore Покрытие кода тестами 95% 2026-03-20 10:49:55 +03:00
arg.go Примеры использования 2026-03-19 16:33:25 +03:00
config.go Заголовка 2026-03-19 12:52:11 +03:00
defaults.go Заголовка 2026-03-19 12:52:11 +03:00
defaults_test.go Заголовка 2026-03-19 12:52:11 +03:00
dotenv.go Заголовка 2026-03-19 12:52:11 +03:00
dotenv_test.go Заголовка 2026-03-19 12:52:11 +03:00
duplicate_test.go Заголовка 2026-03-19 12:52:11 +03:00
env.go Заголовка 2026-03-19 12:52:11 +03:00
env_test.go Заголовка 2026-03-19 12:52:11 +03:00
errors.go Заголовка 2026-03-19 12:52:11 +03:00
go.mod Нормализация модулей 2026-03-20 11:22:00 +03:00
go.sum Нормализация модулей 2026-03-20 11:22:00 +03:00
help.go Примеры использования 2026-03-19 16:33:25 +03:00
help_test.go Покрытие кода тестами 95% 2026-03-20 10:49:55 +03:00
integration_test.go Реализация 2026-03-19 16:15:39 +03:00
json.go Заголовка 2026-03-19 12:52:11 +03:00
json_test.go Заголовка 2026-03-19 12:52:11 +03:00
LICENSE Заголовка 2026-03-19 12:52:11 +03:00
parse_test.go Заголовка 2026-03-19 12:52:11 +03:00
parse_value_test.go Покрытие тестами примерно на 87% 2026-03-20 09:25:14 +03:00
parser.go Реализация 2026-03-19 16:15:39 +03:00
parser_impl.go Добавление глобальной переменной окружения CONFIG_FILE 2026-03-20 11:21:19 +03:00
parser_test.go Добавление глобальной переменной окружения CONFIG_FILE 2026-03-20 11:21:19 +03:00
pointer.go Заголовка 2026-03-19 12:52:11 +03:00
pointer_test.go Заголовка 2026-03-19 12:52:11 +03:00
README.md Добавление глобальной переменной окружения CONFIG_FILE 2026-03-20 11:21:19 +03:00
reflect.go Заголовка 2026-03-19 12:52:11 +03:00
reflect_test.go Покрытие кода тестами 95% 2026-03-20 10:49:55 +03:00
validate_test.go Покрытие тестами примерно на 87% 2026-03-20 09:25:14 +03:00
version_test.go Покрытие тестами примерно на 87% 2026-03-20 09:25:14 +03:00
yaml.go Заголовка 2026-03-19 12:52:11 +03:00
yaml_test.go Покрытие кода тестами 95% 2026-03-20 10:49:55 +03:00

go-simple-args

Go Reference Go Report Card Tests

Библиотека для парсинга аргументов командной строки на Go на основе структур. Поддерживает аргументы командной строки, переменные окружения, .env файлы и конфигурационные файлы YAML/JSON с автоматическим приоритетом.

Особенности

  • Простой API — используйте теги для описания параметров
  • Множественные источники конфигурации — CLI args → Env vars → Config files → Defaults
  • Вложенные структуры — автоматическая поддержка с инициализацией nil указателей
  • Генерация справки — автоматически из тегов help
  • Валидация — поддержка required полей
  • Безопасность — обнаружение дубликатов параметров

Установка

go get git.ymnuktech.ru/ymnuk/go-simple-args

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

Базовое использование

package main

import (
    "fmt"
    "log"
    
    "git.ymnuktech.ru/ymnuk/go-simple-args"
)

type Config struct {
    Port    int    `arg:"--port" default:"8080" help:"Port to listen on"`
    Host    string `arg:"--host" default:"localhost" help:"Host to bind"`
    Verbose bool   `arg:"--verbose" help:"Enable verbose logging"`
}

func main() {
    var cfg Config
    err := arg.MustParse(&cfg)
    if err != nil {
        log.Fatal(err)
    }
    
    fmt.Printf("Starting server on %s:%d\n", cfg.Host, cfg.Port)
}

Использование с обработкой ошибок

var cfg Config
parser, err := arg.NewParser(arg.Config{}, &cfg)
if err != nil {
    log.Fatal(err)
}

err = parser.Parse(os.Args[1:])
if err == arg.ErrHelp {
    parser.WriteHelp(os.Stdout)
    os.Exit(0)
}
if err == arg.ErrRequired {
    parser.WriteHelp(os.Stdout)
    os.Exit(1)
}
if err != nil {
    log.Fatal(err)
}

Теги полей

arg: — Аргументы командной строки

type Config struct {
    // Короткий флаг: -p
    Port int `arg:"-p" default:"8080"`
    
    // Длинный флаг: --host
    Host string `arg:"--host" default:"localhost"`
    
    // Оба флага: -v или --verbose
    Verbose bool `arg:"-v,--verbose"`
    
    // Переменная окружения: APP_NAME
    Name string `arg:"--name,env:APP_NAME"`
    
    // Required поле
    Token string `arg:"--token,required"`
    
    // Игнорировать поле
    Internal string `arg:"-"`
}

default: — Значения по умолчанию

type Config struct {
    Port    int    `default:"8080"`
    Host    string `default:"localhost"`
    Enabled bool   `default:"true"`
    Timeout string `default:"30s"`  // time.Duration
}

help: — Описание для справки

type Config struct {
    Port int `arg:"--port" help:"Port to listen on" default:"8080"`
    Host string `arg:"--host" help:"Host to bind" default:"localhost"`
}

env: — Переменные окружения

type Config struct {
    // Явное имя переменной
    Name string `arg:"--name,env:MY_NAME"`
    
    // С префиксом из Config.EnvPrefix
    // При EnvPrefix: "APP_" → APP_DATABASE_URL
    DatabaseURL string `arg:"--db-url,env:DATABASE_URL"`
}

required — Обязательные поля

type Config struct {
    // Без значения будет ошибка
    APIKey string `arg:"--api-key,required" help:"API key for authentication"`
}

Источники конфигурации

Приоритет (от высшего к низшему)

  1. Аргументы командной строки (наивысший приоритет)
  2. Переменные окружения
  3. Файлы конфигурации (YAML/JSON)
  4. Значения по умолчанию (низший приоритет)

Пример приоритета

type Config struct {
    Port int `arg:"--port" env:PORT default:"8080"`
}
# 1. CLI (приоритет 1)
./app --port 9000    # Port = 9000

# 2. Env (приоритет 2)
PORT=8500 ./app      # Port = 8500

# 3. Config file (приоритет 3)
./app --config config.yaml  # Port из файла

# 4. Default (приоритет 4)
./app                  # Port = 8080

Вложенные структуры

type WebConfig struct {
    Port int    `arg:"--web-port" default:"8080"`
    Host string `arg:"--web-host" default:"localhost"`
}

type DBConfig struct {
    Host     string `arg:"--db-host" default:"localhost"`
    Port     int    `arg:"--db-port" default:"5432"`
    Database string `arg:"--db-name" default:"mydb"`
}

type Config struct {
    Web WebConfig `arg:"-"`
    DB  DBConfig  `arg:"-"`
}

func main() {
    var cfg Config
    arg.MustParse(&cfg)
    // cfg.Web.Port, cfg.DB.Host и т.д.
}

Указатели на структуры

type Config struct {
    Web *WebConfig `arg:"-"`  // Автоматически инициализируется
}

Библиотека автоматически создаст экземпляр WebConfig при парсинге.

Конфигурационные файлы

YAML

# config.yaml
name: myapp
port: 8080
enabled: true

database:
  host: localhost
  port: 5432
type Config struct {
    Name    string `yaml:"name" default:"app"`
    Port    int    `yaml:"port" default:"8080"`
    Enabled bool   `yaml:"enabled" default:"false"`
}

func main() {
    var cfg Config
    p, _ := arg.NewParser(arg.Config{
        ConfigFile: "config.yaml",  // Или используйте переменную окружения CONFIG_FILE
    }, &cfg)
    p.Parse(os.Args[1:])
}

Путь к файлу конфигурации можно указать тремя способами (по приоритету):

  1. Явно в коде: ConfigFile: "config.yaml"
  2. Переменная окружения: CONFIG_FILE=/path/to/config.yaml
  3. Флаг командной строки: --config /path/to/config.yaml

Для Docker: удобно использовать переменную окружения:

ENV CONFIG_FILE=/app/config.yaml

JSON

{
  "name": "myapp",
  "port": 8080,
  "enabled": true
}
type Config struct {
    Name    string `json:"name" default:"app"`
    Port    int    `json:"port" default:"8080"`
    Enabled bool   `json:"enabled" default:"false"`
}

.env файлы

Автоматически загружается файл .env из текущей директории:

# .env
APP_PORT=9000
APP_HOST=0.0.0.0
APP_DEBUG=true
type Config struct {
    Port  int    `arg:"--port,env:APP_PORT" default:"8080"`
    Host  string `arg:"--host,env:APP_HOST" default:"localhost"`
    Debug bool   `arg:"--debug,env:APP_DEBUG" default:"false"`
}

func main() {
    var cfg Config
    arg.MustParse(&cfg)  // .env загрузится автоматически
}

Пользовательский путь к .env

p, _ := arg.NewParser(arg.Config{
    EnvFile: ".env.production",
}, &cfg)
p.Parse(os.Args[1:])

Поддерживаемые типы

  • Целочисленные: int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64
  • С плавающей точкой: float32, float64
  • Строки: string
  • Булевы: bool
  • Время: time.Duration (формат: 1s, 1m, 1h)
  • Указатели на все вышеперечисленные типы
  • Вложенные структуры

Расширенные возможности

Префикс переменных окружения

type Config struct {
    Port int `arg:"--port,env:PORT"`
}

p, _ := arg.NewParser(arg.Config{
    EnvPrefix: "APP_",  // APP_PORT
}, &cfg)

Игнорирование источников

// Игнорировать переменные окружения
p, _ := arg.NewParser(arg.Config{
    IgnoreEnv: true,
}, &cfg)

// Игнорировать значения по умолчанию
p, _ := arg.NewParser(arg.Config{
    IgnoreDefault: true,
}, &cfg)

Обработка ошибок

var cfg Config
p, err := arg.NewParser(arg.Config{}, &cfg)
if err != nil {
    log.Fatal(err)
}

err = p.Parse(os.Args[1:])
switch err {
case nil:
    // Успех
case arg.ErrHelp:
    p.WriteHelp(os.Stdout)
    os.Exit(0)
case arg.ErrRequired:
    fmt.Fprintln(os.Stderr, "Error: required argument missing")
    p.WriteHelp(os.Stderr)
    os.Exit(1)
case arg.ErrDuplicate:
    fmt.Fprintln(os.Stderr, "Error: duplicate argument")
    os.Exit(1)
default:
    fmt.Fprintf(os.Stderr, "Error: %v\n", err)
    os.Exit(1)
}

Примеры

Полное приложение

package main

import (
    "fmt"
    "log"
    "os"
    
    "git.ymnuktech.ru/ymnuk/go-simple-args"
)

type DatabaseConfig struct {
    Host     string `arg:"--db-host" env:DB_HOST default:"localhost"`
    Port     int    `arg:"--db-port" env:DB_PORT default:"5432"`
    Database string `arg:"--db-name" env:DB_NAME default:"mydb"`
    User     string `arg:"--db-user" env:DB_USER,required`
    Password string `arg:"--db-pass" env:DB_PASSWORD,required`
}

type ServerConfig struct {
    Host string `arg:"--host" env:SERVER_HOST default:"0.0.0.0"`
    Port int    `arg:"--port" env:SERVER_PORT default:"8080"`
}

type Config struct {
    Debug    bool           `arg:"--debug" env:DEBUG default:"false"`
    Database DatabaseConfig `arg:"-"`
    Server   ServerConfig   `arg:"-"`
}

func main() {
    var cfg Config
    
    p, err := arg.NewParser(arg.Config{
        EnvPrefix: "APP_",
        EnvFile:   ".env",
    }, &cfg)
    if err != nil {
        log.Fatal(err)
    }
    
    err = p.Parse(os.Args[1:])
    if err == arg.ErrHelp {
        p.WriteHelp(os.Stdout)
        os.Exit(0)
    }
    if err == arg.ErrRequired {
        fmt.Fprintln(os.Stderr, "Error: required argument missing")
        p.WriteHelp(os.Stderr)
        os.Exit(1)
    }
    if err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v\n", err)
        os.Exit(1)
    }
    
    fmt.Printf("Starting server on %s:%d\n", cfg.Server.Host, cfg.Server.Port)
    fmt.Printf("Database: %s@%s:%d/%s\n", 
        cfg.Database.User, cfg.Database.Host, 
        cfg.Database.Port, cfg.Database.Database)
}

Запуск:

# С значениями по умолчанию
./app

# С аргументами командной строки
./app --port 9000 --debug

# С переменными окружения
APP_PORT=9000 APP_DEBUG=true ./app

# С конфигурационным файлом
./app --config config.yaml

# С .env файлом
# .env: APP_PORT=9000, APP_DEBUG=true
./app

Лицензия

MIT License — см. файл LICENSE