1 package client
2
3 import (
4 "bytes"
5 "errors"
6 "fmt"
7 "io"
8 "io/fs"
9 )
10
11
12
13
14
15
16
17 func NewFileRemoteStore(fsys fs.FS, targetDir string) (*FileRemoteStore, error) {
18 if fsys == nil {
19 return nil, errors.New("nil fs.FS")
20 }
21 t := targetDir
22 if t == "" {
23 t = "targets"
24 }
25
26 d, err := fsys.Open(t)
27 if err != nil {
28 return nil, fmt.Errorf("failed to open targets directory %s: %w", t, err)
29 }
30 fi, err := d.Stat()
31 if err != nil {
32 return nil, fmt.Errorf("failed to stat targets directory %s: %w", t, err)
33 }
34 if !fi.IsDir() {
35 return nil, fmt.Errorf("targets directory not a directory %s", t)
36 }
37
38 fsysT, err := fs.Sub(fsys, t)
39 if err != nil {
40 return nil, fmt.Errorf("failed to open targets directory %s: %w", t, err)
41 }
42 return &FileRemoteStore{fsys: fsys, targetDir: fsysT}, nil
43 }
44
45 type FileRemoteStore struct {
46
47 fsys fs.FS
48
49 targetDir fs.FS
50
51
52
53
54 testDir string
55 }
56
57 func (f *FileRemoteStore) GetMeta(name string) (io.ReadCloser, int64, error) {
58 rc, b, err := f.get(f.fsys, name)
59 return handleErrors(name, rc, b, err)
60 }
61
62 func (f *FileRemoteStore) GetTarget(name string) (io.ReadCloser, int64, error) {
63 rc, b, err := f.get(f.targetDir, name)
64 return handleErrors(name, rc, b, err)
65 }
66
67 func (f *FileRemoteStore) get(fsys fs.FS, s string) (io.ReadCloser, int64, error) {
68 if !fs.ValidPath(s) {
69 return nil, 0, fmt.Errorf("invalid path %s", s)
70 }
71
72 b, err := fs.ReadFile(fsys, s)
73 if err != nil {
74 return nil, -1, err
75 }
76 return io.NopCloser(bytes.NewReader(b)), int64(len(b)), nil
77 }
78
79
80
81
82 func handleErrors(name string, rc io.ReadCloser, b int64, err error) (io.ReadCloser, int64, error) {
83 if err == nil {
84 return rc, b, err
85 }
86 if errors.Is(err, fs.ErrNotExist) {
87 return rc, b, ErrNotFound{name}
88 }
89 return rc, b, err
90 }
91
View as plain text