diff --git a/internal/provider/collect.go b/internal/provider/collect.go index 93bf3963e..6658c8067 100644 --- a/internal/provider/collect.go +++ b/internal/provider/collect.go @@ -161,12 +161,15 @@ func merge(sources *fileSources, registerd map[int64]*goMigration) ([]*migration // wholesale as part of migrations. This allows users to build a custom binary that only embeds // the SQL migration files. for version, r := range registerd { - fullpath := "manually registered (no source)" + var fullpath string if s := sources.lookup(TypeGo, version); s != nil { fullpath = s.Fullpath } // Ensure there are no duplicate versions. if existing, ok := migrationLookup[version]; ok { + if fullpath == "" { + fullpath = "manually registered (no source)" + } return nil, fmt.Errorf("found duplicate migration version %d:\n\texisting:%v\n\tcurrent:%v", version, existing.Source.Fullpath, @@ -174,6 +177,7 @@ func merge(sources *fileSources, registerd map[int64]*goMigration) ([]*migration ) } m := &migration{ + // Note, the fullpath may be empty if the migration was registered manually. Source: newSource(TypeGo, fullpath, version), Go: r, } diff --git a/internal/provider/collect_test.go b/internal/provider/collect_test.go index 08834db85..401a1ce40 100644 --- a/internal/provider/collect_test.go +++ b/internal/provider/collect_test.go @@ -254,9 +254,34 @@ func TestMerge(t *testing.T) { check.Number(t, len(migrations), 5) assertMigration(t, migrations[0], newSource(TypeSQL, "00001_foo.sql", 1)) assertMigration(t, migrations[1], newSource(TypeSQL, "00002_bar.sql", 2)) - assertMigration(t, migrations[2], newSource(TypeGo, "manually registered (no source)", 3)) + assertMigration(t, migrations[2], newSource(TypeGo, "", 3)) assertMigration(t, migrations[3], newSource(TypeSQL, "00005_baz.sql", 5)) - assertMigration(t, migrations[4], newSource(TypeGo, "manually registered (no source)", 6)) + assertMigration(t, migrations[4], newSource(TypeGo, "", 6)) + }) + }) + t.Run("partial_go_files_on_disk", func(t *testing.T) { + mapFS := fstest.MapFS{ + "migrations/00001_foo.sql": sqlMapFile, + "migrations/00002_bar.go": &fstest.MapFile{Data: []byte(`package migrations`)}, + } + fsys, err := fs.Sub(mapFS, "migrations") + check.NoError(t, err) + sources, err := collectFileSources(fsys, false, nil) + check.NoError(t, err) + t.Run("unregistered_all", func(t *testing.T) { + migrations, err := merge(sources, map[int64]*goMigration{ + // This is the only Go file on disk. + 2: {version: 2}, + // These are not on disk. Explicitly registered. + 3: {version: 3}, + 6: {version: 6}, + }) + check.NoError(t, err) + check.Number(t, len(migrations), 4) + assertMigration(t, migrations[0], newSource(TypeSQL, "00001_foo.sql", 1)) + assertMigration(t, migrations[1], newSource(TypeGo, "00002_bar.go", 2)) + assertMigration(t, migrations[2], newSource(TypeGo, "", 3)) + assertMigration(t, migrations[3], newSource(TypeGo, "", 6)) }) }) }