package cli import ( "fmt" "os" "path/filepath" initcmd "sunhpc/internal/cli/init" "sunhpc/pkg/config" "sunhpc/pkg/logger" "github.com/spf13/cobra" "github.com/spf13/viper" ) var ( cfgFile string verbose bool noColor bool ) func NewRootCmd() *cobra.Command { cmd := &cobra.Command{ Use: "sunhpc", Short: "SunHPC - HPC集群一体化运维工具", PersistentPreRun: func(cmd *cobra.Command, args []string) { // 设置 CLI 参数 config.CLIParams.Verbose = verbose config.CLIParams.NoColor = noColor config.CLIParams.Config = cfgFile // 初始化配置目录和默认文件 if err := config.InitConfigs(); err != nil { fmt.Fprintf(os.Stderr, "初始化配置目录失败: %v\n", err) os.Exit(1) } // 加载配置(后续调用直接返回缓存) cfg, err := config.LoadConfig() if err != nil { fmt.Fprintf(os.Stderr, "加载配置失败: %v\n", err) os.Exit(1) } // 初始化日志 logger.Init(cfg.Log) // 记录启动信息 logger.Debugf("SunHPC 启动中...") logger.Debugf("配置文件: %s", viper.ConfigFileUsed()) logger.Debugf("日志级别: %s", cfg.Log.Level) logger.Debugf("日志格式: %s", cfg.Log.Format) logger.Debugf("日志输出: %s", cfg.Log.Output) logger.Debugf("日志文件: %s", cfg.Log.LogFile) logger.Debugf("显示颜色: %v", cfg.Log.ShowColor) // 跳过数据库检查,仅在 init db 时检查 if isInitDbCommand(cmd) { return } // 检查数据库文件是否存在 dbPath := filepath.Join(cfg.Database.Path, cfg.Database.Name) if _, err := os.Stat(dbPath); os.IsNotExist(err) { logger.Warnf("数据库文件不存在: %s", dbPath) logger.Errorf("请先运行 sunhpc init db 初始化数据库") os.Exit(1) } logger.Debugf("数据库文件存在: %s", dbPath) }, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } cmd.PersistentFlags().BoolVar( &verbose, "verbose", false, "启用详细日志输出") cmd.PersistentFlags().BoolVar( &noColor, "no-color", false, "禁用彩色输出") cmd.PersistentFlags().StringVar( &cfgFile, "config", "", "配置文件路径 (默认:/etc/sunhpc/config.yaml)") cmd.AddCommand(initcmd.NewInitCmd()) return cmd } func Execute() error { return NewRootCmd().Execute() } func isInitDbCommand(cmd *cobra.Command) bool { // 检查当前命令是否是 db 子命令 if cmd.Name() == "db" { // 检查父命令是否是 init if parent := cmd.Parent(); parent != nil { return parent.Name() == "init" } } return false }