package cmd import ( "fmt" "os" "path/filepath" "github.com/sirupsen/logrus" "github.com/spf13/cobra" "github.com/spf13/viper" ) var cfgFile string // rootCmd is the base command for drive-migrator CLI. var rootCmd = &cobra.Command{ Use: "drive-migrator", Short: "Simple cloud drive migration tool powered by rclone", Long: `Drive Migrator adalah alat baris perintah sederhana untuk memigrasi data antar berbagai cloud drive (misal Google Drive, OneDrive, NextCloud, dll) menggunakan rclone di belakang layar. Fitur: - Migrasi antar berbagai cloud storage - Tracking progress dengan database lokal - Resume migrasi yang terputus - Filter file/folder dengan include/exclude patterns - Logging detail untuk monitoring`, } // Execute runs the root command. func Execute() { if err := rootCmd.Execute(); err != nil { fmt.Println(err) os.Exit(1) } } func init() { cobra.OnInitialize(initConfig, initLogger) // Persistent Flags rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "", "config file (default is $HOME/.drive-migrator.yaml)") rootCmd.PersistentFlags().Bool("debug", false, "enable debug logging") rootCmd.PersistentFlags().String("log-file", "", "log file path (default: logs to stdout)") } func initConfig() { if cfgFile != "" { viper.SetConfigFile(cfgFile) } else { home, err := os.UserHomeDir() if err != nil { fmt.Println(err) os.Exit(1) } viper.AddConfigPath(home) viper.SetConfigName(".drive-migrator") } viper.SetEnvPrefix("DRIVE_MIG") viper.AutomaticEnv() if err := viper.ReadInConfig(); err == nil { fmt.Println("Using config file:", viper.ConfigFileUsed()) } } func initLogger() { logrus.SetFormatter(&logrus.TextFormatter{ FullTimestamp: true, ForceColors: true, }) // Set log level logrus.SetLevel(logrus.InfoLevel) if viper.GetBool("debug") { logrus.SetLevel(logrus.DebugLevel) logrus.Debug("Debug logging enabled") } // Set log file if specified logFile := viper.GetString("log-file") if logFile != "" { // Create log directory if it doesn't exist logDir := filepath.Dir(logFile) if err := os.MkdirAll(logDir, 0755); err != nil { logrus.Fatalf("Failed to create log directory: %v", err) } file, err := os.OpenFile(logFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666) if err != nil { logrus.Fatalf("Failed to open log file: %v", err) } logrus.SetOutput(file) logrus.Infof("Logging to file: %s", logFile) } }