github.com/posener/gitfs@v1.2.2-0.20200410105819-ea4e48d73ab9/internal/githubfs/getatree.go (about) 1 package githubfs 2 3 import ( 4 "context" 5 "encoding/base64" 6 "strings" 7 8 "github.com/pkg/errors" 9 "github.com/posener/gitfs/internal/tree" 10 ) 11 12 // getATree gets github tree using Github's get-a-tree API: 13 // https://developer.github.com/v3/git/trees/#get-a-tree. 14 // The content provider returns the file content only when accessed. 15 type getATree githubfs 16 17 func (fs *getATree) get(ctx context.Context) (tree.Tree, error) { 18 gitTree, _, err := fs.client.Git.GetTree(ctx, fs.owner, fs.repo, fs.ref, true) 19 if err != nil { 20 return nil, errors.Wrap(err, "get git tree") 21 } 22 t := make(tree.Tree) 23 for _, entry := range gitTree.Entries { 24 path := entry.GetPath() 25 if fs.path != "" { 26 if !strings.HasPrefix(path, fs.path) { 27 continue 28 } 29 path = strings.TrimPrefix(path, fs.path) 30 } 31 32 var err error 33 switch entry.GetType() { 34 case "tree": // A directory. 35 if !fs.glob.Match(path, true) { 36 continue 37 } 38 err = t.AddDir(path) 39 case "blob": // A file. 40 if !fs.glob.Match(path, false) { 41 continue 42 } 43 err = t.AddFile(path, entry.GetSize(), fs.contentLoader(entry.GetSHA())) 44 } 45 if err != nil { 46 return nil, errors.Wrapf(err, "adding %s", path) 47 } 48 } 49 return t, nil 50 } 51 52 // contentLoader gets content of git blob according to git sha of that blob. 53 func (fs *getATree) contentLoader(sha string) func(context.Context) ([]byte, error) { 54 return func(ctx context.Context) ([]byte, error) { 55 blob, _, err := fs.client.Git.GetBlob(ctx, fs.owner, fs.repo, sha) 56 if err != nil { 57 return nil, errors.Wrap(err, "failed getting blob") 58 } 59 switch encoding := blob.GetEncoding(); encoding { 60 case "base64": 61 return base64.StdEncoding.DecodeString(blob.GetContent()) 62 default: 63 return nil, errors.Errorf("unexpected encoding: %s", encoding) 64 } 65 } 66 }