code.gitea.io/gitea@v1.19.3/modules/lfs/filesystem_client.go (about) 1 // Copyright 2021 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package lfs 5 6 import ( 7 "context" 8 "io" 9 "net/url" 10 "os" 11 "path/filepath" 12 13 "code.gitea.io/gitea/modules/util" 14 ) 15 16 // FilesystemClient is used to read LFS data from a filesystem path 17 type FilesystemClient struct { 18 lfsdir string 19 } 20 21 // BatchSize returns the preferred size of batchs to process 22 func (c *FilesystemClient) BatchSize() int { 23 return 1 24 } 25 26 func newFilesystemClient(endpoint *url.URL) *FilesystemClient { 27 path, _ := util.FileURLToPath(endpoint) 28 29 lfsdir := filepath.Join(path, "lfs", "objects") 30 31 client := &FilesystemClient{lfsdir} 32 33 return client 34 } 35 36 func (c *FilesystemClient) objectPath(oid string) string { 37 return filepath.Join(c.lfsdir, oid[0:2], oid[2:4], oid) 38 } 39 40 // Download reads the specific LFS object from the target path 41 func (c *FilesystemClient) Download(ctx context.Context, objects []Pointer, callback DownloadCallback) error { 42 for _, object := range objects { 43 p := Pointer{object.Oid, object.Size} 44 45 objectPath := c.objectPath(p.Oid) 46 47 f, err := os.Open(objectPath) 48 if err != nil { 49 return err 50 } 51 52 if err := callback(p, f, nil); err != nil { 53 return err 54 } 55 } 56 return nil 57 } 58 59 // Upload writes the specific LFS object to the target path 60 func (c *FilesystemClient) Upload(ctx context.Context, objects []Pointer, callback UploadCallback) error { 61 for _, object := range objects { 62 p := Pointer{object.Oid, object.Size} 63 64 objectPath := c.objectPath(p.Oid) 65 66 if err := os.MkdirAll(filepath.Dir(objectPath), os.ModePerm); err != nil { 67 return err 68 } 69 70 content, err := callback(p, nil) 71 if err != nil { 72 return err 73 } 74 75 err = func() error { 76 defer content.Close() 77 78 f, err := os.Create(objectPath) 79 if err != nil { 80 return err 81 } 82 83 _, err = io.Copy(f, content) 84 85 return err 86 }() 87 if err != nil { 88 return err 89 } 90 } 91 return nil 92 }