diff --git a/go/core/pkg/cli/db/migrate/migrate.go b/go/core/pkg/cli/db/migrate/migrate.go index 57c355134..2933c4229 100644 --- a/go/core/pkg/cli/db/migrate/migrate.go +++ b/go/core/pkg/cli/db/migrate/migrate.go @@ -217,8 +217,8 @@ func ensureClean(src migrations.Source, mg *migrate.Migrate) error { return nil } -// sourceFileVersions returns the (ascending-sorted) NNN versions parsed from -// every NNN_name.up.sql file in src.FS/src.Dir. +// sourceFileVersions returns the (ascending-sorted) versions parsed from +// every .up.sql file in src.FS/src.Dir whose filename begins with decimal digits. // // The set isn't required to be contiguous — gaps (e.g. a deleted 005) are // real and the missing numbers are treated as not-applicable-to-this-binary. @@ -238,12 +238,8 @@ func sourceFileVersions(src migrations.Source) ([]int, error) { if !strings.HasSuffix(name, ".up.sql") { continue } - parts := strings.SplitN(name, "_", 2) - if len(parts) != 2 { - continue - } - v, err := strconv.Atoi(parts[0]) - if err != nil { + var v int + if _, err := fmt.Sscanf(name, "%d", &v); err != nil { continue } versions = append(versions, v) diff --git a/go/core/pkg/cli/db/migrate/migrate_test.go b/go/core/pkg/cli/db/migrate/migrate_test.go index 96f802296..85c090dfa 100644 --- a/go/core/pkg/cli/db/migrate/migrate_test.go +++ b/go/core/pkg/cli/db/migrate/migrate_test.go @@ -362,3 +362,36 @@ func markDirty(t *testing.T, dsn, table string) { t.Fatalf("mark %s dirty: %v", table, err) } } + +func TestSourceFileVersions(t *testing.T) { + tests := []struct { + name string + files []string + want []int + }{ + {"standard format", []string{"000001_create.up.sql", "000002_alter.up.sql"}, []int{1, 2}}, + {"no underscore", []string{"000003foo.up.sql"}, []int{3}}, + {"no leading digits ignored", []string{"notes.up.sql"}, nil}, + {"down files ignored", []string{"000001_create.down.sql", "000001_create.up.sql"}, []int{1}}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + mfs := fstest.MapFS{} + for _, f := range tt.files { + mfs["m/"+f] = &fstest.MapFile{Data: []byte("-- sql")} + } + got, err := sourceFileVersions(migrations.Source{FS: mfs, Dir: "m"}) + if err != nil { + t.Fatal(err) + } + if len(got) != len(tt.want) { + t.Fatalf("got %v, want %v", got, tt.want) + } + for i := range got { + if got[i] != tt.want[i] { + t.Errorf("[%d] got %d, want %d", i, got[i], tt.want[i]) + } + } + }) + } +}