首次提交:初始化项目代码
This commit is contained in:
@@ -0,0 +1,128 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
)
|
||||
|
||||
// GlobalOptions 全局公共参数,所有子命令共享
|
||||
type GlobalOptions struct {
|
||||
Verbose bool // 详细日志模式
|
||||
Config string // 全局配置文件
|
||||
}
|
||||
|
||||
// SubCommand 通用子命令抽象结构体
|
||||
type SubCommand struct {
|
||||
Name string
|
||||
Description string
|
||||
Flags *flag.FlagSet
|
||||
Run func([]string, GlobalOptions) error
|
||||
}
|
||||
|
||||
// 提前声明变量,避免初始化循环引用
|
||||
var commands map[string]*SubCommand
|
||||
|
||||
// init 初始化子命令,将 FlagSet 的绑定与执行逻辑分离
|
||||
func init() {
|
||||
// --- 初始化 build 命令 ---
|
||||
buildCmd := &SubCommand{
|
||||
Name: "build",
|
||||
Description: "编译构建项目",
|
||||
Flags: flag.NewFlagSet("build", flag.ContinueOnError),
|
||||
}
|
||||
var buildOutput string
|
||||
// 在外部绑定参数,而不是在 Run 里面重新创建 FlagSet
|
||||
buildCmd.Flags.StringVar(&buildOutput, "output", "./dist", "项目构建输出目录")
|
||||
buildCmd.Run = func(args []string, global GlobalOptions) error {
|
||||
if err := buildCmd.Flags.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("[构建成功] 输出目录:%s,全局详细日志:%t,全局配置:%s\n",
|
||||
buildOutput, global.Verbose, global.Config)
|
||||
return nil
|
||||
}
|
||||
|
||||
// --- 初始化 deploy 命令 ---
|
||||
deployCmd := &SubCommand{
|
||||
Name: "deploy",
|
||||
Description: "部署项目到环境",
|
||||
Flags: flag.NewFlagSet("deploy", flag.ContinueOnError),
|
||||
}
|
||||
var deployEnv string
|
||||
deployCmd.Flags.StringVar(&deployEnv, "env", "dev", "部署环境 dev/test/prod")
|
||||
deployCmd.Run = func(args []string, global GlobalOptions) error {
|
||||
if err := deployCmd.Flags.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("[部署成功] 目标环境:%s,全局配置文件:%s\n",
|
||||
deployEnv, global.Config)
|
||||
return nil
|
||||
}
|
||||
|
||||
// 注册子命令
|
||||
commands = map[string]*SubCommand{
|
||||
"build": buildCmd,
|
||||
"deploy": deployCmd,
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 1. 初始化全局参数 FlagSet(独立隔离)
|
||||
var global GlobalOptions
|
||||
globalFlags := flag.NewFlagSet("global", flag.ContinueOnError)
|
||||
globalFlags.BoolVar(&global.Verbose, "verbose", false, "启用详细日志输出")
|
||||
globalFlags.StringVar(&global.Config, "config", "./config.yaml", "全局配置文件路径")
|
||||
|
||||
// 2. 解析全局参数
|
||||
// 注意:flag 库遇到第一个非 Flag 参数(即子命令名称)就会停止解析
|
||||
if err := globalFlags.Parse(os.Args[1:]); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
printHelp(globalFlags)
|
||||
return
|
||||
}
|
||||
fmt.Println("全局参数解析失败:", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 3. 获取剩余参数(子命令 + 子命令参数)
|
||||
remainingArgs := globalFlags.Args()
|
||||
if len(remainingArgs) == 0 {
|
||||
printHelp(globalFlags)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// 4. 路由分发执行子命令
|
||||
cmdName := remainingArgs[0]
|
||||
if cmd, exists := commands[cmdName]; exists {
|
||||
if err := cmd.Run(remainingArgs[1:], global); err != nil {
|
||||
if err == flag.ErrHelp {
|
||||
// 当子命令触发 -h 时,打印该子命令专属的帮助信息
|
||||
fmt.Printf("\n===== 子命令 [%s] 帮助信息 =====\n", cmd.Name)
|
||||
fmt.Printf("说明:%s\n\n用法:%s [选项]\n\n选项:\n", cmd.Description, cmd.Name)
|
||||
cmd.Flags.PrintDefaults()
|
||||
return
|
||||
}
|
||||
fmt.Printf("子命令执行失败:%v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("❌ 未知子命令:%s\n", cmdName)
|
||||
printHelp(globalFlags)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// printHelp 统一打印全局帮助信息
|
||||
func printHelp(globalFlags *flag.FlagSet) {
|
||||
fmt.Println("===== 项目工程化 CLI 工具 =====")
|
||||
fmt.Println("用法:tool [全局选项] <子命令> [子命令选项]")
|
||||
fmt.Println("\n全局选项:")
|
||||
globalFlags.PrintDefaults()
|
||||
|
||||
fmt.Println("\n可用子命令:")
|
||||
for _, cmd := range commands {
|
||||
fmt.Printf(" %-10s %s\n", cmd.Name, cmd.Description)
|
||||
}
|
||||
fmt.Println("\n提示:使用 'tool <子命令> -h' 查看子命令详细帮助")
|
||||
}
|
||||
Reference in New Issue
Block a user