diff --git a/goose.go b/goose.go index 0240bb6..6dc0714 100644 --- a/goose.go +++ b/goose.go @@ -3,9 +3,33 @@ package goose import ( "database/sql" "fmt" + "sync" ) +var ( + duplicateCheckOnce sync.Once + minVersion = int64(0) + maxVersion = int64((1 << 63) - 1) +) + +func checkVersionDuplicates(dir string) error { + migrations, err := CollectMigrations(dir, minVersion, maxVersion) + if err != nil { + return err + } + + // Try sorting all migrations, so we get panic on any duplicates. + ms := migrationSorter(migrations) + ms.Sort(true) + ms.Sort(false) + return nil +} + func Run(command string, db *sql.DB, dir string, args ...string) error { + if err := checkVersionDuplicates(dir); err != nil { + return err + } + switch command { case "up": if err := Up(db, dir); err != nil { diff --git a/migrate.go b/migrate.go index 0a1c8cc..9478162 100644 --- a/migrate.go +++ b/migrate.go @@ -43,7 +43,7 @@ func (ms migrationSorter) Len() int { return len(ms) } func (ms migrationSorter) Swap(i, j int) { ms[i], ms[j] = ms[j], ms[i] } func (ms migrationSorter) Less(i, j int) bool { if ms[i].Version == ms[j].Version { - panic(fmt.Sprintf("goose: duplicate version %v detected:\n%v\n%v", ms[i].Version, ms[i].Source, ms[j].Source)) + log.Fatalf("goose: duplicate version %v detected:\n%v\n%v", ms[i].Version, ms[i].Source, ms[j].Source) } return ms[i].Version < ms[j].Version } @@ -259,7 +259,7 @@ func EnsureDBVersion(db *sql.DB) (int64, error) { toSkip = append(toSkip, row.VersionId) } - panic("failure in EnsureDBVersion()") + panic("unreachable") } // Create the goose_db_version table diff --git a/status.go b/status.go index 9f7820d..8138f97 100644 --- a/status.go +++ b/status.go @@ -10,9 +10,7 @@ import ( func Status(db *sql.DB, dir string) error { // collect all migrations - min := int64(0) - max := int64((1 << 63) - 1) - migrations, err := CollectMigrations(dir, min, max) + migrations, err := CollectMigrations(dir, minVersion, maxVersion) if err != nil { return err }