# qflag
**Repository Path**: MM-Q/qflag
## Basic Information
- **Project Name**: qflag
- **Description**: QFlag 是一个专为 Go 语言设计的命令行参数解析库, 提供了丰富的功能和优雅的 API, 帮助开发者快速构建专业的命令行工具。它支持多种标志类型、子命令、环境变量绑定、自动补全等高级特性, 同时保持简单易用的设计理念。
- **Primary Language**: Go
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 1
- **Forks**: 0
- **Created**: 2025-06-13
- **Last Updated**: 2026-05-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: Go语言, 参数解析, Cli
## README
# 🚀 QFlag
[](https://golang.org/) [](https://opensource.org/licenses/MIT) [](https://gitee.com/MM-Q/qflag) [](https://github.com/QiaoMuDe/qflag) [](https://deepwiki.com/QiaoMuDe/qflag)
*泛型设计 • 自动路由 • 类型安全 • 并发安全 • 自动补全 • 智能纠错*
---
## 📖 项目简介
QFlag 是一个专为 Go 语言设计的命令行参数解析库, 提供了丰富的功能和优雅的 API, 帮助开发者快速构建专业的命令行工具。它支持多种标志类型、子命令、环境变量绑定、自动补全等高级特性, 同时保持简单易用的设计理念。
### ✨ 核心特性
| 特性分类 | 功能描述 |
|---------|---------|
| **类型系统** | 泛型设计、类型安全、17种标志类型(基础类型、枚举、时间、大小、集合) |
| **验证机制** | 标志验证、互斥组、必需组、条件性必需组、标志依赖关系 |
| **命令系统** | 子命令支持、命令/标志别名、嵌套命令、自动路由 |
| **配置环境** | 环境变量绑定、配置优先级(命令行 > 环境变量 > 默认值)、全局根命令 |
| **开发体验** | 智能纠错、Shell补全(Bash/Pwsh)、自动生成帮助文档、双语支持 |
| **工程特性** | 并发安全(读写锁保护)、零外部依赖、标准Go错误处理 |
---
## 🔗 项目地址
该项目同时托管在 Gitee 和 GitHub 上,您可以选择合适的平台访问:
| 平台 | 地址 | 描述 |
| ------------------ | ----------------------------------------------------------- | -------------------------- |
| 🔴**Gitee** | [gitee.com/MM-Q/qflag](https://gitee.com/MM-Q/qflag) | 国内访问更快,主要开发仓库 |
| ⚫**GitHub** | [github.com/QiaoMuDe/qflag](https://github.com/QiaoMuDe/qflag) | 国际化平台,同步更新 |
---
## 📦 安装指南
使用 `go get` 命令安装:
```bash
go get -u gitee.com/MM-Q/qflag
```
然后在代码中导入:
```go
import "gitee.com/MM-Q/qflag"
```
---
## 💡 使用示例
### 🚀 全局根命令 (推荐)
QFlag 提供了全局根命令 `qflag.Root`, 这是最简单、最直接的使用方式。**推荐优先使用**全局根命令作为命令行工具的入口点。
```go
package main
import (
"fmt"
"gitee.com/MM-Q/qflag"
)
func main() {
// 直接使用全局根命令创建标志
name := qflag.Root.String("name", "n", "用户名", "guest")
age := qflag.Root.Int("age", "a", "年龄", 18)
verbose := qflag.Root.Bool("verbose", "v", "详细模式", false)
// 配置全局命令
qflag.Root.SetDesc("示例应用程序")
qflag.Root.SetVersion("1.0.0")
// 解析命令行参数
if err := qflag.Parse(); err != nil {
fmt.Printf("解析错误: %v\n", err)
return
}
// 使用参数
fmt.Printf("用户名: %s\n", name.Get())
fmt.Printf("年龄: %d\n", age.Get())
fmt.Printf("详细模式: %t\n", verbose.Get())
fmt.Printf("非标志参数: %v\n", qflag.Root.Args())
}
```
#### 全局根命令的优势
- 🎯 **简单易用**: 无需手动创建命令实例, 直接使用
- 🚀 **零配置**: 自动使用可执行文件名作为命令名
- 🔧 **功能完整**: 支持所有 QFlag 的高级功能
- 📦 **统一入口**: 所有操作都通过 `qflag.Root` 访问
#### 全局根命令支持的便捷函数
```go
// 解析函数
qflag.Parse() // 解析命令行参数
qflag.ParseOnly() // 仅解析当前命令
qflag.ParseAndRoute() // 解析并路由到子命令
// 子命令管理
qflag.AddSubCmds(cmd1, cmd2) // 添加子命令
qflag.AddSubCmdFrom([]Command{cmd1, cmd2}) // 从切片添加子命令
```
### 高级用法
#### 智能纠错功能
QFlag 内置智能纠错功能,当用户输入错误的子命令或标志时,会自动推荐相似的选项。
```bash
# 子命令纠错示例
$ myapp cnfig
myapp: 'cnfig' is not a valid command. See 'myapp --help'.
The most similar commands are
config
# 标志纠错示例
$ myapp config --verb
myapp: unknown flag: '--verb'
The most similar flags are
--verbose
-v
```
智能纠错功能无需额外配置,自动集成在解析流程中。
#### 使用全局根命令的子命令支持
```go
package main
import (
"fmt"
"gitee.com/MM-Q/qflag"
)
func main() {
// 配置全局根命令
qflag.Root.SetDesc("命令行工具")
qflag.Root.SetVersion("1.0.0")
// 创建全局标志
verbose := qflag.Root.Bool("verbose", "v", "详细输出", false)
// 创建子命令
listCmd := qflag.NewCmd("list", "ls", qflag.ContinueOnError)
listCmd.SetDesc("列出所有项目")
listCmd.Bool("all", "a", "显示所有项目", false)
addCmd := qflag.NewCmd("add", "a", qflag.ContinueOnError)
addCmd.SetDesc("添加新项目")
addCmd.String("name", "n", "项目名称", "")
// 添加子命令到全局根命令
qflag.AddSubCmds(listCmd, addCmd)
// 解析并路由
if err := qflag.ParseAndRoute(); err != nil {
fmt.Printf("错误: %v\n", err)
return
}
// 如果是根命令执行
if qflag.Root.NArg() == 0 {
fmt.Printf("详细模式: %t\n", verbose.Get())
fmt.Println("使用 'help' 查看可用命令")
}
}
```
#### 便捷方法创建标志
```go
package main
import (
"fmt"
"os"
"time"
"gitee.com/MM-Q/qflag"
)
func main() {
cmd := qflag.NewCmd("server", "s", qflag.ContinueOnError)
// 使用便捷方法创建多个标志
cmd.String("host", "h", "主机地址", "localhost")
cmd.Uint("port", "p", "端口号", 8080)
cmd.Duration("timeout", "t", "超时时间", time.Second*30)
cmd.Bool("debug", "d", "调试模式", false)
fmt.Printf("成功添加 %d 个标志\n", len(cmd.Flags()))
}
```
#### 使用全局根命令的互斥标志组
```go
package main
import (
"fmt"
"gitee.com/MM-Q/qflag"
)
func main() {
// 配置全局根命令
qflag.Root.SetDesc("格式转换工具")
// 使用全局根命令创建互斥标志
jsonFlag := qflag.Root.Bool("json", "j", "JSON 格式", false)
xmlFlag := qflag.Root.Bool("xml", "x", "XML 格式", false)
yamlFlag := qflag.Root.Bool("yaml", "y", "YAML 格式", false)
// 添加互斥组到全局根命令
qflag.Root.AddMutexGroup("format", []string{"json", "xml", "yaml"}, false)
// 解析参数
if err := qflag.Parse(); err != nil {
fmt.Printf("错误: %v\n", err)
return
}
// 使用参数
if jsonFlag.Get() {
fmt.Println("使用 JSON 格式")
} else if xmlFlag.Get() {
fmt.Println("使用 XML 格式")
} else if yamlFlag.Get() {
fmt.Println("使用 YAML 格式")
}
}
```
#### 使用全局根命令的必需标志组
```go
package main
import (
"fmt"
"gitee.com/MM-Q/qflag"
)
func main() {
// 配置全局根命令
qflag.Root.SetDesc("数据库连接工具")
// 使用全局根命令创建必需标志
hostFlag := qflag.Root.String("host", "h", "主机地址", "")
portFlag := qflag.Root.Uint("port", "p", "端口号", 0)
// 添加普通必需组到全局根命令 - 所有标志都必须设置
qflag.Root.AddRequiredGroup("connection", []string{"host", "port"}, false)
// 添加条件性必需组 - 如果使用其中一个则必须同时使用
qflag.Root.AddRequiredGroup("database", []string{"dbhost", "dbport"}, true)
// 解析参数
if err := qflag.Parse(); err != nil {
fmt.Printf("错误: %v\n", err)
return
}
// 使用参数
fmt.Printf("连接到 %s:%d\n", hostFlag.Get(), portFlag.Get())
}
```
#### 条件性必需组
条件性必需组允许定义一组标志,如果组中任何一个标志被使用,则所有标志都必须被设置。
```go
// 创建条件性必需组的标志
dbHostFlag := qflag.Root.String("dbhost", "dh", "数据库主机", "")
dbPortFlag := qflag.Root.Uint("dbport", "dp", "数据库端口", 0)
// 添加条件性必需组 - 第三个参数为 true
qflag.Root.AddRequiredGroup("database", []string{"dbhost", "dbport"}, true)
```
#### 标志依赖关系
定义标志之间的依赖约束,支持互斥依赖(`DepMutex`)和必需依赖(`DepRequired`)。
```go
// 创建标志
remoteFlag := qflag.Root.Bool("remote", "r", "使用远程模式", false)
sslFlag := qflag.Root.Bool("ssl", "s", "启用SSL", false)
certFlag := qflag.Root.String("cert", "c", "证书路径", "")
keyFlag := qflag.Root.String("key", "k", "密钥路径", "")
// 互斥依赖:远程模式与本地路径互斥
qflag.Root.AddFlagDependency("remote_mutex_local", "remote", []string{"local-path"}, qflag.DepMutex)
// 必需依赖:SSL模式需要证书和密钥
qflag.Root.AddFlagDependency("ssl_requires_cert_key", "ssl", []string{"cert", "key"}, qflag.DepRequired)
```
#### 环境变量绑定
QFlag 支持通过环境变量设置标志值,优先级:命令行参数 > 环境变量 > 默认值。
```go
package main
import (
"fmt"
"os"
"gitee.com/MM-Q/qflag"
)
func main() {
cmd := qflag.NewCmd("app", "", qflag.ContinueOnError)
// 设置环境变量前缀
cmd.SetEnvPrefix("MYAPP")
// 创建标志
hostFlag := cmd.String("host", "H", "主机地址", "localhost")
portFlag := cmd.Int("port", "p", "端口号", 8080)
// 方式1: 手动指定环境变量名
hostFlag.BindEnv("HOST_ADDR") // 绑定到 MYAPP_HOST_ADDR
// 方式2: 自动绑定(使用标志长名称大写)
portFlag.AutoBindEnv() // 绑定到 MYAPP_PORT
// 方式3: 批量自动绑定所有标志
// cmd.AutoBindAllEnv()
if err := cmd.Parse(os.Args[1:]); err != nil {
fmt.Printf("错误: %v\n", err)
return
}
fmt.Printf("主机: %s, 端口: %d\n", hostFlag.GetStr(), portFlag.GetInt())
}
```
**三种绑定方式对比:**
| 方式 | 方法 | 适用场景 | 环境变量名 |
|------|------|----------|------------|
| 手动指定 | `BindEnv("NAME")` | 需要自定义名称 | `前缀_NAME` |
| 自动绑定 | `AutoBindEnv()` | 单个标志绑定 | `前缀_标志长名大写` |
| 批量绑定 | `AutoBindAllEnv()` | 批量绑定所有标志 | `前缀_标志长名大写` |
---
## 📚 API 文档概述
QFlag 提供了简洁而强大的 API, 主要包含以下核心组件:
### 核心概念
- **Command (命令)** - 命令行工具的核心, 支持标志管理、参数解析、子命令等功能
- **Flag (标志)** - 命令行参数的抽象, 支持多种数据类型
- **MutexGroup (互斥组)** - 确保组内只有一个标志被设置
- **RequiredGroup (必需组)** - 确保组内所有标志都被设置, 支持普通必需组和条件性必需组两种模式
- **FlagDependency (标志依赖)** - 定义触发标志与目标标志之间的约束关系(互斥或必需)
- **智能纠错** - 输入错误的子命令或标志时,自动推荐相似的选项
### 便捷方法
Command 类型提供了丰富的便捷方法来创建各种类型的标志, 无需手动创建和添加标志:
```go
// 字符串和布尔标志
nameFlag := cmd.String("name", "n", "用户名", "guest")
verboseFlag := cmd.Bool("verbose", "v", "详细输出", false)
// 数值类型标志
portFlag := cmd.Uint("port", "p", "端口号", 8080)
timeoutFlag := cmd.Duration("timeout", "t", "超时时间", time.Second*30)
// 集合类型标志
filesFlag := cmd.StringSlice("files", "f", "文件列表", []string{})
tagsFlag := cmd.IntSlice("tags", "", "标签列表", []int{})
```
### 详细的 API 文档
完整的 API 文档和示例代码, 请参考项目中的 [_examples/](_examples/) 目录和源代码中的注释。
### 📚 更多文档
- [API 文档](APIDOC.md) - 完整的 API 参考
- [qflag-cli](qflag-cli) - CLI 开发技能包,包含快速开始指南、核心概念速查、完整开发规范和示例代码(适用于 AI 技能调用和人类学习)
---
## ⚙️ 配置选项说明
### 错误处理策略
QFlag 提供了三种错误处理策略:
- **ContinueOnError** - 遇到错误继续解析
- **ExitOnError** - 遇到错误立即退出
- **ReturnOnError** - 遇到错误返回错误
### CmdOpts 配置选项
`CmdOpts` 提供了配置现有命令的方式,包含命令的所有可配置属性。完整字段说明请参考 [APIDOC.md](APIDOC.md)。
#### 使用示例
```go
// 创建命令并添加标志
cmd := qflag.NewCmd("myapp", "m", qflag.ExitOnError)
cmd.String("host", "H", "主机地址", "localhost")
cmd.Int("port", "p", "端口号", 8080)
// 创建配置选项
opts := &qflag.CmdOpts{
Desc: "我的应用程序",
Version: "1.0.0",
UseChinese: true,
EnvPrefix: "MYAPP",
AutoBindEnv: true,
}
// 应用配置
cmd.ApplyOpts(opts)
```
#### 特点
- **部分配置**: 未设置的属性不会被修改,保留原有值
- **批量设置**: 一次性设置多个命令属性
- **结构化管理**: 通过结构体集中管理配置
### 禁用标志解析
通过设置 `DisableFlagParsing: true` 可将所有参数(包括 `--flag` 形式)作为位置参数处理。
**使用场景:**
- 透传参数给外部命令(如 `kubectl exec`)
- SSH 包装器
- 需要保留原始参数的场景
**配置方式:**
```go
opts := &qflag.CmdOpts{
DisableFlagParsing: true,
}
cmd.ApplyOpts(opts)
```
完整示例请参考 [_examples/cmdopts](_examples/cmdopts) 目录。
### 隐藏命令
设置 `Hidden: true` 后,命令不会显示在帮助信息中,但仍可通过命令行正常调用。
**使用场景:**
- 内部调试命令
- 已弃用但仍需兼容的命令
- 高级或实验性功能
**配置方式:**
```go
opts := &qflag.CmdOpts{
Hidden: true,
}
cmd.ApplyOpts(opts)
// 或
cmd.SetHidden(true)
```
完整示例请参考 [_examples/cmdopts](_examples/cmdopts) 目录。
---
## 📄 许可证和贡献指南
### 许可证
本项目采用 MIT 许可证。详见 [LICENSE](LICENSE) 文件。
### 贡献指南
我们欢迎任何形式的贡献!
#### 贡献方式
1. Fork 本仓库
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 创建 Pull Request
#### 代码规范
- 遵循 Go 语言代码规范
- 添加适当的注释
- 编写测试用例
- 确保所有测试通过
- 更新相关文档
#### 问题反馈
如果您发现 bug 或有功能建议, 请:
- 搜索现有的 issues
- 创建新的 issue, 详细描述问题
- 提供复现步骤和环境信息
---
## 📞 联系方式和相关链接
### 相关资源
- 📦 **仓库地址**: [https://gitee.com/MM-Q/qflag.git](https://gitee.com/MM-Q/qflag.git)
- 📖 **文档**: [项目文档](https://gitee.com/MM-Q/qflag)
- 🐛 **问题反馈**: [Issues](https://gitee.com/MM-Q/qflag/issues)
- 💬 **讨论**: [Discussions](https://gitee.com/MM-Q/qflag/discussions)
### 联系方式
- 📧 **邮箱**: [提交 Issue](https://gitee.com/MM-Q/qflag/issues)
---
## 🙏 致谢
感谢所有为本项目做出贡献的开发者!
---
**[⬆ 返回顶部](#top)**
Made with ❤️ by QFlag Team