package cli import ( "fmt" "os" "strings" "time" ) // CommandType 定义命令类型 type CommandType int const ( SERVER CommandType = iota CONFIG TEST VERSION HELP UNKNOWN ) // Command 表示CLI命令的结构 // 该结构体包含命令的所有参数和配置 type Command struct { // 基本命令信息 Type CommandType `json:"type"` Name string `json:"name"` Description string `json:"description"` Aliases []string `json:"aliases"` Usage string `json:"usage"` // 位置参数 Args []string `json:"args"` ArgsCount int `json:"args_count"` // 标志参数 Flags map[string]string `json:"flags"` Booleans map[string]bool `json:"booleans"` Integers map[string]int64 `json:"integers"` Floats map[string]float64 `json:"floats"` // 选项参数 Options map[string][]string `json:"options"` // 环境变量 EnvVars map[string]string `json:"env_vars"` // 配置文件 ConfigFile string `json:"config_file"` Config interface{} `json:"config"` // 执行信息 Executed bool `json:"executed"` ExecutedAt time.Time `json:"executed_at"` Duration time.Duration `json:"duration"` ExitCode int `json:"exit_code"` Output string `json:"output"` Error error `json:"error"` // 上下文信息 WorkingDir string `json:"working_dir"` UserID string `json:"user_id,omitempty"` SessionID string `json:"session_id,omitempty"` // 调试信息 Debug bool `json:"debug"` Verbose bool `json:"verbose"` Quiet bool `json:"quiet"` DryRun bool `json:"dry_run"` // 自定义数据 Custom map[string]interface{} `json:"custom,omitempty"` } // NewCommand 创建新的命令实例 // 返回包含基本信息的Command结构体 func NewCommand(cmdType CommandType, name, description string) *Command { return &Command{ Type: cmdType, Name: name, Description: description, Args: make([]string, 0), Flags: make(map[string]string), Booleans: make(map[string]bool), Integers: make(map[string]int64), Floats: make(map[string]float64), Options: make(map[string][]string), EnvVars: make(map[string]string), WorkingDir: getCurrentWorkingDir(), Custom: make(map[string]interface{}), } } // NewServerCommand 创建服务器命令 // 返回配置好的服务器命令实例 func NewServerCommand() *Command { cmd := NewCommand(SERVER, "server", "Start the subconverter server") cmd.Usage = "server [flags]" cmd.Aliases = []string{"serve", "start"} // 默认标志 cmd.Booleans["debug"] = false cmd.Booleans["verbose"] = false cmd.Integers["port"] = 25500 cmd.Flags["host"] = "0.0.0.0" cmd.Flags["config"] = "" return cmd } // NewConfigCommand 创建配置命令 // 返回配置好的配置命令实例 func NewConfigCommand() *Command { cmd := NewCommand(CONFIG, "config", "Manage configuration") cmd.Usage = "config [flags]" cmd.Aliases = []string{"conf", "cfg"} return cmd } // NewTestCommand 创建测试命令 // 返回配置好的测试命令实例 func NewTestCommand() *Command { cmd := NewCommand(TEST, "test", "Run tests") cmd.Usage = "test [flags]" cmd.Aliases = []string{"t"} cmd.Booleans["verbose"] = false cmd.Booleans["cover"] = false cmd.Flags["run"] = "" cmd.Flags["output"] = "" return cmd } // NewVersionCommand 创建版本命令 // 返回配置好的版本命令实例 func NewVersionCommand() *Command { cmd := NewCommand(VERSION, "version", "Show version information") cmd.Usage = "version [flags]" cmd.Aliases = []string{"v", "ver"} cmd.Booleans["verbose"] = false cmd.Booleans["short"] = false return cmd } // NewHelpCommand 创建帮助命令 // 返回配置好的帮助命令实例 func NewHelpCommand() *Command { cmd := NewCommand(HELP, "help", "Show help information") cmd.Usage = "help [command]" cmd.Aliases = []string{"h", "?"} return cmd } // AddArg 添加位置参数 func (c *Command) AddArg(arg string) { c.Args = append(c.Args, arg) c.ArgsCount = len(c.Args) } // AddArgs 添加多个位置参数 func (c *Command) AddArgs(args ...string) { c.Args = append(c.Args, args...) c.ArgsCount = len(c.Args) } // SetFlag 设置字符串标志 func (c *Command) SetFlag(key, value string) { c.Flags[key] = value } // SetBoolean 设置布尔标志 func (c *Command) SetBoolean(key string, value bool) { c.Booleans[key] = value } // SetInteger 设置整数标志 func (c *Command) SetInteger(key string, value int64) { c.Integers[key] = value } // SetFloat 设置浮点数标志 func (c *Command) SetFloat(key string, value float64) { c.Floats[key] = value } // AddOption 添加选项参数 func (c *Command) AddOption(key string, values ...string) { if c.Options == nil { c.Options = make(map[string][]string) } c.Options[key] = append(c.Options[key], values...) } // SetEnvVar 设置环境变量 func (c *Command) SetEnvVar(key, value string) { if c.EnvVars == nil { c.EnvVars = make(map[string]string) } c.EnvVars[key] = value } // GetArg 获取位置参数 func (c *Command) GetArg(index int) (string, bool) { if index < 0 || index >= len(c.Args) { return "", false } return c.Args[index], true } // GetFlag 获取字符串标志 func (c *Command) GetFlag(key string) (string, bool) { value, exists := c.Flags[key] return value, exists } // GetBoolean 获取布尔标志 func (c *Command) GetBoolean(key string) (bool, bool) { value, exists := c.Booleans[key] return value, exists } // GetInteger 获取整数标志 func (c *Command) GetInteger(key string) (int64, bool) { value, exists := c.Integers[key] return value, exists } // GetFloat 获取浮点数标志 func (c *Command) GetFloat(key string) (float64, bool) { value, exists := c.Floats[key] return value, exists } // GetOptions 获取选项参数 func (c *Command) GetOptions(key string) ([]string, bool) { value, exists := c.Options[key] return value, exists } // GetEnvVar 获取环境变量 func (c *Command) GetEnvVar(key string) (string, bool) { value, exists := c.EnvVars[key] return value, exists } // HasFlag 检查是否有指定标志 func (c *Command) HasFlag(key string) bool { _, exists := c.Flags[key] return exists } // HasBoolean 检查是否有指定布尔标志 func (c *Command) HasBoolean(key string) bool { _, exists := c.Booleans[key] return exists } // HasOption 检查是否有指定选项 func (c *Command) HasOption(key string) bool { _, exists := c.Options[key] return exists } // ArgCount 返回位置参数数量 func (c *Command) ArgCount() int { return len(c.Args) } // IsExecuted 检查命令是否已执行 func (c *Command) IsExecuted() bool { return c.Executed } // IsSuccessful 检查命令是否成功执行 func (c *Command) IsSuccessful() bool { return c.Executed && c.ExitCode == 0 } // SetConfig 设置配置信息 func (c *Command) SetConfig(config interface{}) { c.Config = config } // SetConfigFile 设置配置文件路径 func (c *Command) SetConfigFile(path string) { c.ConfigFile = path } // SetOutput 设置输出信息 func (c *Command) SetOutput(output string) { c.Output = output } // SetError 设置错误信息 func (c *Command) SetError(err error) { c.Error = err c.ExitCode = 1 } // MarkExecuted 标记命令为已执行 func (c *Command) MarkExecuted() { c.Executed = true c.ExecutedAt = time.Now() } // MarkSuccessful 标记命令为成功执行 func (c *Command) MarkSuccessful() { c.MarkExecuted() c.ExitCode = 0 } // MarkFailed 标记命令为执行失败 func (c *Command) MarkFailed(exitCode int) { c.MarkExecuted() c.ExitCode = exitCode } // SetDuration 设置执行持续时间 func (c *Command) SetDuration(duration time.Duration) { c.Duration = duration } // AddCustom 添加自定义数据 func (c *Command) AddCustom(key string, value interface{}) { if c.Custom == nil { c.Custom = make(map[string]interface{}) } c.Custom[key] = value } // GetCustom 获取自定义数据 func (c *Command) GetCustom(key string) (interface{}, bool) { value, exists := c.Custom[key] return value, exists } // Validate 验证命令的有效性 func (c *Command) Validate() error { if c.Name == "" { return fmt.Errorf("command name cannot be empty") } if c.Type < SERVER || c.Type > UNKNOWN { return fmt.Errorf("invalid command type: %d", c.Type) } // 验证必需的参数 switch c.Type { case SERVER: if port, exists := c.Integers["port"]; exists && (port < 1 || port > 65535) { return fmt.Errorf("invalid port number: %d", port) } case CONFIG: if len(c.Args) == 0 { return fmt.Errorf("config command requires a subcommand") } case TEST: if len(c.Args) == 0 { return fmt.Errorf("test command requires a subcommand") } } return nil } // GetUsage 返回使用说明 func (c *Command) GetUsage() string { if c.Usage != "" { return c.Usage } return c.Name } // GetFullUsage 返回完整的使用说明 func (c *Command) GetFullUsage() string { var builder strings.Builder builder.WriteString(fmt.Sprintf("Usage: %s", c.GetUsage())) if c.Description != "" { builder.WriteString(fmt.Sprintf("\n\n%s", c.Description)) } if len(c.Aliases) > 0 { builder.WriteString(fmt.Sprintf("\n\nAliases: %s", strings.Join(c.Aliases, ", "))) } // 添加位置参数说明 if len(c.Args) > 0 { builder.WriteString("\n\nArguments:") for i, arg := range c.Args { builder.WriteString(fmt.Sprintf("\n %d: %s", i+1, arg)) } } // 添加标志说明 if len(c.Flags) > 0 || len(c.Booleans) > 0 || len(c.Integers) > 0 || len(c.Floats) > 0 { builder.WriteString("\n\nFlags:") for key, value := range c.Flags { builder.WriteString(fmt.Sprintf("\n --%s=%s", key, value)) } for key, value := range c.Booleans { builder.WriteString(fmt.Sprintf("\n --%s (default: %t)", key, value)) } for key, value := range c.Integers { builder.WriteString(fmt.Sprintf("\n --%s=%d", key, value)) } for key, value := range c.Floats { builder.WriteString(fmt.Sprintf("\n --%s=%f", key, value)) } } return builder.String() } // Clone 创建命令的副本 func (c *Command) Clone() *Command { clone := &Command{ Type: c.Type, Name: c.Name, Description: c.Description, Usage: c.Usage, ArgsCount: c.ArgsCount, ConfigFile: c.ConfigFile, Config: c.Config, Executed: c.Executed, ExecutedAt: c.ExecutedAt, Duration: c.Duration, ExitCode: c.ExitCode, Output: c.Output, Error: c.Error, WorkingDir: c.WorkingDir, UserID: c.UserID, SessionID: c.SessionID, Debug: c.Debug, Verbose: c.Verbose, Quiet: c.Quiet, DryRun: c.DryRun, } // 深拷贝切片 if len(c.Aliases) > 0 { clone.Aliases = make([]string, len(c.Aliases)) copy(clone.Aliases, c.Aliases) } if len(c.Args) > 0 { clone.Args = make([]string, len(c.Args)) copy(clone.Args, c.Args) } // 深拷贝映射 if len(c.Flags) > 0 { clone.Flags = make(map[string]string) for k, v := range c.Flags { clone.Flags[k] = v } } if len(c.Booleans) > 0 { clone.Booleans = make(map[string]bool) for k, v := range c.Booleans { clone.Booleans[k] = v } } if len(c.Integers) > 0 { clone.Integers = make(map[string]int64) for k, v := range c.Integers { clone.Integers[k] = v } } if len(c.Floats) > 0 { clone.Floats = make(map[string]float64) for k, v := range c.Floats { clone.Floats[k] = v } } if len(c.Options) > 0 { clone.Options = make(map[string][]string) for k, v := range c.Options { clone.Options[k] = make([]string, len(v)) copy(clone.Options[k], v) } } if len(c.EnvVars) > 0 { clone.EnvVars = make(map[string]string) for k, v := range c.EnvVars { clone.EnvVars[k] = v } } if len(c.Custom) > 0 { clone.Custom = make(map[string]interface{}) for k, v := range c.Custom { clone.Custom[k] = v } } return clone } // String 返回命令的字符串表示 func (c *Command) String() string { if c.Executed { return fmt.Sprintf("%s (executed in %v, exit code: %d)", c.Name, c.Duration, c.ExitCode) } return fmt.Sprintf("%s (not executed)", c.Name) } // GetCurrentWorkingDir 获取当前工作目录 func getCurrentWorkingDir() string { if dir, err := os.Getwd(); err == nil { return dir } return "." } // CommandTypeToString 将命令类型转换为字符串 func CommandTypeToString(cmdType CommandType) string { switch cmdType { case SERVER: return "server" case CONFIG: return "config" case TEST: return "test" case VERSION: return "version" case HELP: return "help" default: return "unknown" } } // StringToCommandType 将字符串转换为命令类型 func StringToCommandType(s string) CommandType { switch strings.ToLower(s) { case "server", "serve", "start": return SERVER case "config", "conf", "cfg": return CONFIG case "test", "t": return TEST case "version", "v", "ver": return VERSION case "help", "h", "?": return HELP default: return UNKNOWN } }