diff options
| author | Paul Buetow <paul@buetow.org> | 2026-04-14 11:19:50 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-04-14 11:19:50 +0300 |
| commit | 55593e14ee2a4225d1db1058da9d8d1f663225b6 (patch) | |
| tree | 5fdd9830dd6411f348be28dbed2085e1806148ce /internal/recordsdir | |
| parent | 2bc4e64acf93f04c8871d964d75f041ada57f89d (diff) | |
refactor: use fs.FS for aggregate and DB import (ask v3)
Decouple Aggregator and ImportFromDir from direct os.Open by routing
through io/fs: NewAggregatorFS, ImportFromFS, recordsdir.ListNonEmptyFilesFS.
NewAggregator and ImportFromDir wrap os.DirFS for backward compatibility.
Add fstest.MapFS tests for recordsdir, aggregate, and ImportFromFS.
Made-with: Cursor
Diffstat (limited to 'internal/recordsdir')
| -rw-r--r-- | internal/recordsdir/recordsdir.go | 45 | ||||
| -rw-r--r-- | internal/recordsdir/recordsdir_test.go | 16 |
2 files changed, 55 insertions, 6 deletions
diff --git a/internal/recordsdir/recordsdir.go b/internal/recordsdir/recordsdir.go index 9f3ce5b..94f7f0e 100644 --- a/internal/recordsdir/recordsdir.go +++ b/internal/recordsdir/recordsdir.go @@ -1,7 +1,9 @@ package recordsdir import ( + "io/fs" "os" + "path" "path/filepath" "strings" ) @@ -19,22 +21,53 @@ func HostFromFileName(name string) string { return host } -func ListNonEmptyFiles(dir string) ([]Entry, error) { - entries, err := os.ReadDir(dir) +func listRecordsFileNames(fsys fs.FS, root string) ([]string, error) { + entries, err := fs.ReadDir(fsys, root) if err != nil { return nil, err } - var out []Entry + var names []string for _, e := range entries { if e.IsDir() || !strings.HasSuffix(e.Name(), ".records") { continue } - path := filepath.Join(dir, e.Name()) - info, err := os.Stat(path) + rel := path.Join(root, e.Name()) + info, err := fs.Stat(fsys, rel) if err != nil || info.Size() == 0 { continue } - out = append(out, Entry{Path: path, Host: HostFromFileName(e.Name())}) + names = append(names, e.Name()) + } + return names, nil +} + +// ListNonEmptyFilesFS returns non-empty .records files under root within fsys. +func ListNonEmptyFilesFS(fsys fs.FS, root string) ([]Entry, error) { + names, err := listRecordsFileNames(fsys, root) + if err != nil { + return nil, err + } + var out []Entry + for _, name := range names { + out = append(out, Entry{ + Path: path.Join(root, name), + Host: HostFromFileName(name), + }) + } + return out, nil +} + +func ListNonEmptyFiles(dir string) ([]Entry, error) { + names, err := listRecordsFileNames(os.DirFS(dir), ".") + if err != nil { + return nil, err + } + var out []Entry + for _, name := range names { + out = append(out, Entry{ + Path: filepath.Join(dir, name), + Host: HostFromFileName(name), + }) } return out, nil } diff --git a/internal/recordsdir/recordsdir_test.go b/internal/recordsdir/recordsdir_test.go index bee8d67..5e72d9d 100644 --- a/internal/recordsdir/recordsdir_test.go +++ b/internal/recordsdir/recordsdir_test.go @@ -4,6 +4,7 @@ import ( "os" "path/filepath" "testing" + "testing/fstest" ) func TestHostFromFileName(t *testing.T) { @@ -56,3 +57,18 @@ func TestListNonEmptyFiles_ReadError(t *testing.T) { t.Fatal("expected error") } } + +func TestListNonEmptyFilesFS_MapFS(t *testing.T) { + m := fstest.MapFS{ + "skip.txt": &fstest.MapFile{Data: []byte("x"), Mode: 0o644}, + "empty.records": &fstest.MapFile{Data: nil, Mode: 0o644}, + "h1.records": &fstest.MapFile{Data: []byte("line\n"), Mode: 0o644}, + } + entries, err := ListNonEmptyFilesFS(m, ".") + if err != nil { + t.Fatal(err) + } + if len(entries) != 1 || entries[0].Host != "h1" || entries[0].Path != "h1.records" { + t.Fatalf("got %#v", entries) + } +} |
