package migration import ( "flag" "log" "os" "os/exec" "gopkg.in/yaml.v3" "gorm.io/driver/postgres" "gorm.io/gorm" "gorm.io/gorm/schema" eu "simrs-vx/internal/domain/main-entities/user" ) type Config struct { DbCfg DbConf `yaml:"dbCfg"` } type DbConf struct { DSN string `yaml:"dsn"` MaxOpenConns int `yaml:"maxOpenConns"` MaxIdleConns int `yaml:"maxIdleConns"` MaxIdleTime int `yaml:"maxIdleTime"` } func Migrate() { // Your existing config loading code... cfgFile := "./config.yml" flag.StringVar(&cfgFile, "config-file", "./config.yml", "Configuration path (default=./config.yaml)") flag.Parse() yamlFile, err := os.ReadFile(cfgFile) if err != nil { log.Fatalf("%v", err) } var cfg Config err = yaml.Unmarshal(yamlFile, &cfg) if err != nil { log.Fatal(err) } argsWithProg := os.Args if len(argsWithProg) > 1 { switch argsWithProg[1] { case "apply": atlasApply(cfg.DbCfg.DSN) case "generate": atlasGenerate(cfg.DbCfg.DSN) case "status": atlasStatus(cfg.DbCfg.DSN) case "gorm": // Fallback to GORM if needed gormMigrate(cfg.DbCfg) default: log.Println("Unknown command. Use: apply, generate, status, or gorm") } } else { // Default: apply Atlas migrations atlasApply(cfg.DbCfg.DSN) } } func atlasApply(url string) { log.Println("Applying Atlas migrations...") cmd := exec.Command("atlas", "migrate", "apply", "--dir", "file://migrations", "--url", url) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Printf("Atlas migration failed: %v", err) log.Println("Try running 'go run migration.go generate' first") } else { log.Println("Atlas migrations applied successfully") } } func atlasGenerate(url string) { log.Println("Generating Atlas migration from GORM models...") // First, create tables with GORM to get the schema log.Println("Step 1: Creating schema with GORM...") gormCreateSchema(url) // Then inspect and create migration log.Println("Step 2: Generating Atlas migration...") cmd := exec.Command("atlas", "migrate", "diff", "auto_migration", "--dir", "file://migrations", "--dev-url", "docker://postgres/17/dev?search_path=public", "--to", url) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Printf("Atlas generation failed: %v", err) } else { log.Println("Atlas migration generated successfully") } } func atlasStatus(url string) { log.Println("Checking Atlas migration status...") cmd := exec.Command("atlas", "migrate", "status", "--dir", "file://migrations", "--url", url) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { log.Printf("Atlas status failed: %v", err) } } func gormCreateSchema(dsn string) { db, err := gorm.Open(postgres.Open(dsn), &gorm.Config{ NamingStrategy: schema.NamingStrategy{ SingularTable: true, NoLowerCase: true, }, }) if err != nil { log.Fatal(err) } modelList := []any{ &eu.User{}, // Add other models here } if err := db.AutoMigrate(modelList...); err != nil { log.Fatal(err) } log.Println("Schema created with GORM") } func gormMigrate(dbConf DbConf) { // Your original GORM migrate code as fallback log.Println("Using GORM AutoMigrate...") // ... your existing GORM code here }