Restructure the monorepo into clear top-level directories: - backend/: Go module root (cmd, internal, pkg, configs, migrations, docs/swagger, scripts, tests, go.mod, Makefile, .air.toml) - deploy/: Docker (Dockerfile, docker-compose*), quickstart, fluentd - docs/: project documentation + reports/ (moved from repo root) - AGENTS.md: new AI coding-agent guide at repo root Update all references to the new layout: - Dockerfile: COPY backend/go.mod, COPY backend/ (context = repo root) - docker-compose files: context ../.., dockerfile deploy/docker/Dockerfile, env_file ../../.env, volume mounts ../../backend:/app - deploy/quickstart/compose.yaml: dockerfile deploy/docker/Dockerfile - CI: working-directory: backend for go commands, file deploy/docker/Dockerfile, coverage path backend/coverage.out, health_check backend/scripts/ - backend/Makefile: docker target uses -f ../deploy/docker/Dockerfile ../ - README: architecture tree, quickstart, config paths updated Move root stray scripts (rename_models.*, run_m11_tests.sh, verify_build.sh, gorm_bool_main.go) to backend/scripts/legacy/. All moves via git mv to preserve history. Build, vet, SQLite tests, and docker compose config verified.
109 lines
3.0 KiB
Go
109 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/gochat/gochat/internal/config"
|
|
"github.com/gochat/gochat/internal/database"
|
|
)
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
printUsage()
|
|
os.Exit(1)
|
|
}
|
|
|
|
command := os.Args[1]
|
|
|
|
// Load config to get database connection info
|
|
cfg, err := config.Load()
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
|
|
dbURL := cfg.Database.MigrateDSN()
|
|
migrationsPath := cfg.Database.GetMigrationsPath()
|
|
|
|
switch command {
|
|
case "up":
|
|
if err := database.RunMigrations(dbURL, migrationsPath); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error running migrations up: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println("Migrations applied successfully (up)")
|
|
|
|
case "down":
|
|
if err := database.RollbackMigrations(dbURL, migrationsPath); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error running migrations down: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Println("Migrations rolled back successfully (down)")
|
|
|
|
case "force":
|
|
if len(os.Args) < 3 {
|
|
fmt.Fprintf(os.Stderr, "Error: 'force' requires a version argument\n")
|
|
printUsage()
|
|
os.Exit(1)
|
|
}
|
|
version, err := strconv.Atoi(os.Args[2])
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: invalid version number '%s': %v\n", os.Args[2], err)
|
|
os.Exit(1)
|
|
}
|
|
if err := database.ForceVersion(dbURL, migrationsPath, version); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error forcing version %d: %v\n", version, err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Migration version forced to %d\n", version)
|
|
|
|
case "version":
|
|
version, dirty, err := database.CurrentVersion(dbURL, migrationsPath)
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error getting current version: %v\n", err)
|
|
os.Exit(1)
|
|
}
|
|
if dirty {
|
|
fmt.Printf("Current version: %d (DIRTY — a migration partially failed)\n", version)
|
|
} else {
|
|
fmt.Printf("Current version: %d\n", version)
|
|
}
|
|
|
|
case "steps":
|
|
if len(os.Args) < 3 {
|
|
fmt.Fprintf(os.Stderr, "Error: 'steps' requires a step count argument\n")
|
|
printUsage()
|
|
os.Exit(1)
|
|
}
|
|
steps, err := strconv.Atoi(os.Args[2])
|
|
if err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error: invalid step count '%s': %v\n", os.Args[2], err)
|
|
os.Exit(1)
|
|
}
|
|
if err := database.MigrateSteps(dbURL, migrationsPath, steps); err != nil {
|
|
fmt.Fprintf(os.Stderr, "Error running %d migration steps: %v\n", steps, err)
|
|
os.Exit(1)
|
|
}
|
|
fmt.Printf("Applied %d migration steps successfully\n", steps)
|
|
|
|
default:
|
|
fmt.Fprintf(os.Stderr, "Unknown command: %s\n", command)
|
|
printUsage()
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
func printUsage() {
|
|
fmt.Println("Usage: migrate <command> [args]")
|
|
fmt.Println("")
|
|
fmt.Println("Commands:")
|
|
fmt.Println(" up Apply all pending migrations")
|
|
fmt.Println(" down Rollback all migrations")
|
|
fmt.Println(" force <v> Force version to v (fix dirty state)")
|
|
fmt.Println(" version Show current migration version")
|
|
fmt.Println(" steps <n> Apply n steps (positive=up, negative=down)")
|
|
fmt.Println("")
|
|
fmt.Println("Environment: Uses database config from Viper (config.yaml)")
|
|
} |