github.com/benchkram/bob@v0.0.0-20240314204020-b7a57f2f9be9/pkg/buildinfostore/protostore.go (about) 1 package buildinfostore 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 9 "github.com/benchkram/bob/bobtask/buildinfo" 10 "github.com/benchkram/bob/bobtask/buildinfo/protos" 11 "github.com/benchkram/bob/pkg/file" 12 "github.com/benchkram/errz" 13 14 "google.golang.org/protobuf/proto" 15 ) 16 17 type ps struct { 18 dir string 19 } 20 21 // NewProtoStore creates a proto store. The caller is responsible to pass an existing directory 22 func NewProtoStore(dir string) Store { 23 return &ps{dir: dir} 24 } 25 26 // NewBuildInfo creates a new build info file. 27 func (ps *ps) NewBuildInfo(id string, info *buildinfo.I) (err error) { 28 defer errz.Recover(&err) 29 30 m := info.ToProto(id) 31 32 b, err := proto.Marshal(m) 33 errz.Fatal(err) 34 35 err = os.WriteFile(filepath.Join(ps.dir, id), b, 0666) 36 errz.Fatal(err) 37 38 return nil 39 } 40 41 // GetArtifact opens a file 42 func (ps *ps) GetBuildInfo(id string) (info *buildinfo.I, err error) { 43 defer errz.Recover(&err) 44 45 f, err := os.Open(filepath.Join(ps.dir, id)) 46 if err != nil { 47 return nil, ErrBuildInfoDoesNotExist 48 } 49 errz.Fatal(err) 50 defer f.Close() 51 52 b, err := io.ReadAll(f) 53 errz.Fatal(err) 54 55 protoInfo := &protos.BuildInfo{} 56 57 err = proto.Unmarshal(b, protoInfo) 58 errz.Fatal(err) 59 60 if !isValid(protoInfo) { 61 return nil, ErrBuildInfoInvalid 62 } 63 64 return buildinfo.FromProto(protoInfo), nil 65 } 66 67 func (ps *ps) GetBuildInfos() (_ []*buildinfo.I, err error) { 68 defer errz.Recover(&err) 69 70 entries, err := os.ReadDir(ps.dir) 71 errz.Fatal(err) 72 73 var buildInfos []*buildinfo.I 74 for _, entry := range entries { 75 if entry.IsDir() { 76 continue 77 } 78 79 data, err := os.ReadFile(filepath.Join(ps.dir, entry.Name())) 80 errz.Fatal(err) 81 82 bi := &protos.BuildInfo{} 83 err = proto.Unmarshal(data, bi) 84 errz.Fatal(err) 85 86 if !isValid(bi) { 87 return nil, ErrBuildInfoInvalid 88 } 89 90 buildInfos = append(buildInfos, buildinfo.FromProto(bi)) 91 } 92 93 return buildInfos, nil 94 } 95 96 func isValid(bi *protos.BuildInfo) bool { 97 return bi.Meta != nil 98 } 99 100 func (ps *ps) Clean() (err error) { 101 defer errz.Recover(&err) 102 103 homeDir, err := os.UserHomeDir() 104 errz.Fatal(err) 105 if ps.dir == "/" || ps.dir == homeDir { 106 return fmt.Errorf("Cleanup of %s is not allowed", ps.dir) 107 } 108 109 entrys, err := os.ReadDir(ps.dir) 110 errz.Fatal(err) 111 112 for _, entry := range entrys { 113 if entry.IsDir() { 114 continue 115 } 116 _ = os.Remove(filepath.Join(ps.dir, entry.Name())) 117 } 118 119 return nil 120 } 121 122 func (ps *ps) BuildInfoExists(id string) bool { 123 return file.Exists(filepath.Join(ps.dir, id)) 124 }