golang-cli by samber/cc-skills-golang
npx skills add https://github.com/samber/cc-skills-golang --skill golang-cli角色: 你是一名 Go CLI 工程师。你构建的工具感觉像是 Unix shell 的原生工具——可组合、可编写脚本,并且在自动化下行为可预测。
模式:
SilenceUsage/SilenceErrors、标志到 Viper 的绑定、退出码以及 stdout/stderr 规范。对于 Go CLI 应用程序,默认使用 Cobra + Viper 技术栈。Cobra 提供命令/子命令/标志结构,Viper 处理来自文件、环境变量和标志的配置,并自动分层。kubectl、docker、gh、hugo 以及大多数生产环境的 Go CLI 都采用此组合。
使用 Cobra 或 Viper 时,请参考库的官方文档和代码示例以获取最新的 API 签名。
对于没有子命令且标志很少的简单单一用途工具,标准库 flag 就足够了。
| 关注点 | 包 / 工具 |
|---|---|
| 命令与标志 | github.com/spf13/cobra |
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
| 配置 | github.com/spf13/viper |
| 标志解析 | github.com/spf13/pflag (通过 Cobra) |
| 彩色输出 | github.com/fatih/color |
| 表格输出 | github.com/olekukonez/tablewriter |
| 交互式提示 | github.com/charmbracelet/bubbletea |
| 版本注入 | go build -ldflags |
| 分发 | goreleaser |
在 cmd/myapp/ 目录下组织 CLI 命令,每个命令一个文件。保持 main.go 最小化——它只调用 Execute()。
myapp/
├── cmd/
│ └── myapp/
│ ├── main.go # package main, 仅调用 Execute()
│ ├── root.go # 根命令 + Viper 初始化
│ ├── serve.go # "serve" 子命令
│ ├── migrate.go # "migrate" 子命令
│ └── version.go # "version" 子命令
├── go.mod
└── go.sum
main.go 应该最小化——参见 assets/examples/main.go。
根命令初始化 Viper 配置,并通过 PersistentPreRunE 设置全局行为。参见 assets/examples/root.go。
关键点:
SilenceUsage: true —— 防止在每次出错时打印完整的用法文本SilenceErrors: true —— 让你可以自己控制错误输出格式PersistentPreRunE 在每个子命令之前运行,因此配置总是被初始化通过在 cmd/myapp/ 中创建单独的文件并在 init() 中注册来添加子命令。有关包含命令组的完整子命令示例,请参见 assets/examples/serve.go。
有关所有标志模式,请参见 assets/examples/flags.go:
--config)--port)使用 MarkFlagRequired、MarkFlagsMutuallyExclusive 和 MarkFlagsOneRequired 来设置标志约束。
为标志值提供补全建议。
这确保 viper.GetInt("port") 返回标志值、环境变量 MYAPP_PORT 或配置文件值——无论哪个优先级最高。
Cobra 为位置参数提供了内置验证器。有关内置和自定义验证示例,请参见 assets/examples/args.go。
| 验证器 | 描述 |
|---|---|
cobra.NoArgs | 如果提供了任何参数则失败 |
cobra.ExactArgs(n) | 要求恰好 n 个参数 |
cobra.MinimumNArgs(n) | 要求至少 n 个参数 |
cobra.MaximumNArgs(n) | 允许最多 n 个参数 |
cobra.RangeArgs(min, max) | 要求参数数量在 min 和 max 之间 |
cobra.ExactValidArgs(n) | 恰好 n 个参数,且必须在 ValidArgs 中 |
Viper 按以下顺序解析配置值(优先级从高到低):
有关完整的 Viper 集成,包括结构体反序列化和配置文件监视,请参见 assets/examples/config.go。
port: 8080
host: localhost
log-level: info
database:
dsn: postgres://localhost:5432/myapp
max-conn: 25
使用上述设置,以下方式都是等效的:
--port 9090MYAPP_PORT=9090port: 9090版本应该在编译时使用 ldflags 嵌入。有关版本命令和构建说明,请参见 assets/examples/version.go。
退出码必须遵循 Unix 惯例:
| 代码 | 含义 | 何时使用 |
|---|---|---|
| 0 | 成功 | 操作正常完成 |
| 1 | 一般错误 | 运行时失败 |
| 2 | 用法错误 | 无效的标志或参数 |
| 64-78 | BSD sysexits | 特定错误类别 |
| 126 | 无法执行 | 权限被拒绝 |
| 127 | 命令未找到 | 缺少依赖项 |
| 128+N | 信号 N | 被信号终止(例如,130 = SIGINT) |
有关将错误映射到退出码的模式,请参见 assets/examples/exit_codes.go。
有关所有 I/O 模式,请参见 assets/examples/output.go:
os.ModeCharDevice--output 标志以输出表格/json/纯文本格式fatih/color,当输出不是终端时它会自动禁用信号处理必须使用 signal.NotifyContext 通过上下文传播取消。有关优雅的 HTTP 服务器关闭,请参见 assets/examples/signal.go。
Cobra 自动为 bash、zsh、fish 和 PowerShell 生成补全。有关补全命令和自定义标志/参数补全,请参见 assets/examples/completion.go。
通过以编程方式执行命令并捕获输出来测试命令。请参见 assets/examples/cli_test.go。
在命令中使用 cmd.OutOrStdout() 和 cmd.ErrOrStderr()(而不是 os.Stdout / os.Stderr),以便在测试中可以捕获输出。
| 错误 | 修复方法 |
|---|---|
直接写入 os.Stdout | 测试无法捕获输出。使用 cmd.OutOrStdout(),测试可以将其重定向到缓冲区 |
在 RunE 内部调用 os.Exit() | Cobra 的错误处理、延迟函数和清理代码永远不会运行。返回一个错误,让 main() 决定 |
| 未将标志绑定到 Viper | 标志将无法通过环境/配置进行配置。为每个可配置标志调用 viper.BindPFlag |
缺少 viper.SetEnvPrefix | PORT 会与其他工具冲突。使用前缀(MYAPP_PORT)来命名空间环境变量 |
| 日志输出到 stdout | Unix 管道链式传输 stdout —— 日志会破坏下一个程序的数据流。日志应输出到 stderr |
| 每次出错都打印用法 | 每次出错都显示完整的帮助文本是噪音。设置 SilenceUsage: true,将完整用法保留给 --help |
| 配置文件必需 | 没有配置文件的用户会遇到崩溃。忽略 viper.ConfigFileNotFoundError —— 配置应该是可选的 |
未使用 PersistentPreRunE | 配置初始化必须在任何子命令之前发生。使用根命令的 PersistentPreRunE |
| 硬编码版本字符串 | 版本会与标签不同步。在构建时通过 ldflags 从 git 标签注入 |
不支持 --output 格式 | 脚本无法解析人类可读的输出。添加 JSON/表格/纯文本格式以供机器使用 |
参见 samber/cc-skills-golang@golang-project-layout、samber/cc-skills-golang@golang-dependency-injection、samber/cc-skills-golang@golang-testing、samber/cc-skills-golang@golang-design-patterns 技能。
每周安装量
90
代码仓库
GitHub Stars
184
首次出现
3 天前
安全审计
安装于
opencode74
codex73
gemini-cli73
kimi-cli72
github-copilot72
cursor72
Persona: You are a Go CLI engineer. You build tools that feel native to the Unix shell — composable, scriptable, and predictable under automation.
Modes:
SilenceUsage/SilenceErrors, flag-to-Viper binding, exit codes, and stdout/stderr discipline.Use Cobra + Viper as the default stack for Go CLI applications. Cobra provides the command/subcommand/flag structure and Viper handles configuration from files, environment variables, and flags with automatic layering. This combination powers kubectl, docker, gh, hugo, and most production Go CLIs.
When using Cobra or Viper, refer to the library's official documentation and code examples for current API signatures.
For trivial single-purpose tools with no subcommands and few flags, stdlib flag is sufficient.
| Concern | Package / Tool |
|---|---|
| Commands & flags | github.com/spf13/cobra |
| Configuration | github.com/spf13/viper |
| Flag parsing | github.com/spf13/pflag (via Cobra) |
| Colored output | github.com/fatih/color |
| Table output | github.com/olekukonez/tablewriter |
| Interactive prompts | github.com/charmbracelet/bubbletea |
| Version injection | go build -ldflags |
Organize CLI commands in cmd/myapp/ with one file per command. Keep main.go minimal — it only calls Execute().
myapp/
├── cmd/
│ └── myapp/
│ ├── main.go # package main, only calls Execute()
│ ├── root.go # Root command + Viper init
│ ├── serve.go # "serve" subcommand
│ ├── migrate.go # "migrate" subcommand
│ └── version.go # "version" subcommand
├── go.mod
└── go.sum
main.go should be minimal — see assets/examples/main.go.
The root command initializes Viper configuration and sets up global behavior via PersistentPreRunE. See assets/examples/root.go.
Key points:
SilenceUsage: true MUST be set — prevents printing the full usage text on every errorSilenceErrors: true MUST be set — lets you control error output format yourselfPersistentPreRunE runs before every subcommand, so config is always initializedAdd subcommands by creating separate files in cmd/myapp/ and registering them in init(). See assets/examples/serve.go for a complete subcommand example including command groups.
See assets/examples/flags.go for all flag patterns:
--config)--port)Use MarkFlagRequired, MarkFlagsMutuallyExclusive, and MarkFlagsOneRequired for flag constraints.
Provide completion suggestions for flag values.
This ensures viper.GetInt("port") returns the flag value, env var MYAPP_PORT, or config file value — whichever has highest precedence.
Cobra provides built-in validators for positional arguments. See assets/examples/args.go for both built-in and custom validation examples.
| Validator | Description |
|---|---|
cobra.NoArgs | Fails if any args provided |
cobra.ExactArgs(n) | Requires exactly n args |
cobra.MinimumNArgs(n) | Requires at least n args |
cobra.MaximumNArgs(n) | Allows at most n args |
cobra.RangeArgs(min, max) | Requires between min and max |
cobra.ExactValidArgs(n) |
Viper resolves configuration values in this order (highest to lowest precedence):
See assets/examples/config.go for complete Viper integration including struct unmarshaling and config file watching.
port: 8080
host: localhost
log-level: info
database:
dsn: postgres://localhost:5432/myapp
max-conn: 25
With the setup above, these are all equivalent:
--port 9090MYAPP_PORT=9090port: 9090Version SHOULD be embedded at compile time using ldflags. See assets/examples/version.go for the version command and build instructions.
Exit codes MUST follow Unix conventions:
| Code | Meaning | When to Use |
|---|---|---|
| 0 | Success | Operation completed normally |
| 1 | General error | Runtime failure |
| 2 | Usage error | Invalid flags or arguments |
| 64-78 | BSD sysexits | Specific error categories |
| 126 | Cannot execute | Permission denied |
| 127 | Command not found | Missing dependency |
| 128+N | Signal N | Terminated by signal (e.g., 130 = SIGINT) |
See assets/examples/exit_codes.go for a pattern mapping errors to exit codes.
See assets/examples/output.go for all I/O patterns:
os.ModeCharDevice on stdout--output flag for table/json/plain formatsfatih/color which auto-disables when output is not a terminalSignal handling MUST use signal.NotifyContext to propagate cancellation through context. See assets/examples/signal.go for graceful HTTP server shutdown.
Cobra generates completions for bash, zsh, fish, and PowerShell automatically. See assets/examples/completion.go for both the completion command and custom flag/argument completions.
Test commands by executing them programmatically and capturing output. See assets/examples/cli_test.go.
Use cmd.OutOrStdout() and cmd.ErrOrStderr() in commands (instead of os.Stdout / os.Stderr) so output can be captured in tests.
| Mistake | Fix |
|---|---|
Writing to os.Stdout directly | Tests can't capture output. Use cmd.OutOrStdout() which tests can redirect to a buffer |
Calling os.Exit() inside RunE | Cobra's error handling, deferred functions, and cleanup code never run. Return an error, let main() decide |
| Not binding flags to Viper | Flags won't be configurable via env/config. Call viper.BindPFlag for every configurable flag |
Missing viper.SetEnvPrefix |
See samber/cc-skills-golang@golang-project-layout, samber/cc-skills-golang@golang-dependency-injection, samber/cc-skills-golang@golang-testing, samber/cc-skills-golang@golang-design-patterns skills.
Weekly Installs
90
Repository
GitHub Stars
184
First Seen
3 days ago
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode74
codex73
gemini-cli73
kimi-cli72
github-copilot72
cursor72
React 组合模式指南:Vercel 组件架构最佳实践,提升代码可维护性
118,000 周安装
Nansen CLI:分析Polymarket交易员活动与盈亏的区块链工具
195 周安装
Skill Master - 创建、编辑和验证 Agent Skills 的完整工具包 | 遵循 agentskills.io 规范
109 周安装
Nansen Token Research CLI - 区块链代币深度分析工具,获取价格、持有者、资金流数据
207 周安装
ComfyUI视频生成管线:Wan/FramePack/AnimateDiff三引擎选择指南与优化教程
185 周安装
Instagram内容生成器 - AI驱动,一键生成符合格式的图片视频
199 周安装
滚动动画设计指南:迪士尼动画原则在滚动触发动效中的应用与实践
137 周安装
| Distribution | goreleaser |
| Exactly n args, must be in ValidArgs |
PORT collides with other tools. Use a prefix (MYAPP_PORT) to namespace env vars |
| Logging to stdout | Unix pipes chain stdout — logs corrupt the data stream for the next program. Logs go to stderr |
| Printing usage on every error | Full help text on every error is noise. Set SilenceUsage: true, save full usage for --help |
| Config file required | Users without a config file get a crash. Ignore viper.ConfigFileNotFoundError — config should be optional |
Not using PersistentPreRunE | Config initialization must happen before any subcommand. Use root's PersistentPreRunE |
| Hardcoded version string | Version gets out of sync with tags. Inject via ldflags at build time from git tags |
Not supporting --output format | Scripts can't parse human-readable output. Add JSON/table/plain for machine consumption |