Cobra CLI Flag Config Precedence

Resolve CLI configuration with explicit precedence from flags over environment over config file, with typed defaults and validation.

GoConfig Management

Code

snippet
package main

import (
	"fmt"
	"os"
	"time"

	"github.com/spf13/cobra"
)

type SyncConfig struct {
	Workers     int
	Timeout     time.Duration
	Environment string
}

func resolveConfig(flagWorkers int, flagTimeout time.Duration,
	flagEnv string, fileEnv string, fileWorkers int,
) SyncConfig {
	// 优先级:命令行标志 > 环境变量 > 配置文件 > 内置默认值
	workers := 4 // 默认值
	if fileWorkers > 0 {
		workers = fileWorkers
	}
	if env := os.Getenv("SYNC_WORKERS"); env != "" {
		if parsed, ok := atoiSafe(env); ok {
			workers = parsed
		}
	}
	if flagWorkers > 0 {
		workers = flagWorkers
	}

	environment := fileEnv
	if env := os.Getenv("SYNC_ENV"); env != "" {
		environment = env
	}
	if flagEnv != "" {
		environment = flagEnv
	}

	return SyncConfig{
		Workers:     workers,
		Timeout:     flagTimeout,
		Environment: environment,
	}
}

func atoiSafe(s string) (int, bool) {
	n := 0
	if s == "" {
		return 0, false
	}
	for _, ch := range s {
		if ch < '0' || ch > '9' {
			return 0, false
		}
		n = n*10 + int(ch-'0')
		if n > 10_000 {
			return 0, false
		}
	}
	return n, true
}

func main() {
	var (
		workers int
		timeout time.Duration
		env     string
	)

	root := &cobra.Command{
		Use:   "sync",
		Short: "Sync catalog data across regions",
		Run: func(cmd *cobra.Command, args []string) {
			cfg := resolveConfig(workers, timeout, env, "staging", 8)
			fmt.Printf("resolved: workers=%d timeout=%s env=%s\n",
				cfg.Workers, cfg.Timeout, cfg.Environment)
		},
	}

	root.Flags().IntVarP(&workers, "workers", "w", 0, "concurrent workers")
	root.Flags().DurationVarP(&timeout, "timeout", "t", 30*time.Second, "per-batch timeout")
	root.Flags().StringVarP(&env, "env", "e", "", "target environment")

	root.Execute()
}