package migrate import ( "errors" "fmt" "io" "io/fs" "path/filepath" "ariga.io/atlas/sql/migrate" ) var _ migrate.Dir = (*readOnlyFSDir)(nil) type readOnlyFSDir struct { fs.FS } func (m readOnlyFSDir) WriteFile(string, []byte) error { return errors.New("migration directory is read-only") } func (m readOnlyFSDir) Files() ([]migrate.File, error) { files, err := fs.ReadDir(m, ".") if err != nil { return nil, err } filesList := make([]migrate.File, 0, len(files)) for idx := range files { f := files[idx] if f.IsDir() || filepath.Ext(f.Name()) != ".sql" { continue } scriptFile, err := m.Open(f.Name()) if err != nil { return nil, fmt.Errorf("failed to open %s: %w", f.Name(), err) } defer func() { _ = scriptFile.Close() }() scriptData, err := io.ReadAll(scriptFile) if err != nil { return nil, fmt.Errorf("failed to read %s: %w", f.Name(), err) } filesList = append(filesList, migrate.NewLocalFile(f.Name(), scriptData)) } return filesList, nil } func (m readOnlyFSDir) Checksum() (migrate.HashFile, error) { var hf migrate.HashFile f, err := m.Open(migrate.HashFileName) if err != nil { return nil, err } defer func() { _ = f.Close() }() sumData, err := io.ReadAll(f) if err != nil { return nil, fmt.Errorf("failed to %s: %w", migrate.HashFileName, err) } if err := hf.UnmarshalText(sumData); err != nil { return nil, fmt.Errorf("failed to unmarshal %s: %w", migrate.HashFileName, err) } return hf, nil }