this repo has no description
1package xrpc 2 3import ( 4 "encoding/json" 5 "net/http" 6 "path/filepath" 7 "time" 8 9 "tangled.sh/tangled.sh/core/api/tangled" 10 "tangled.sh/tangled.sh/core/knotserver/git" 11 xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors" 12) 13 14func (x *Xrpc) RepoTree(w http.ResponseWriter, r *http.Request) { 15 ctx := r.Context() 16 17 repo := r.URL.Query().Get("repo") 18 repoPath, err := x.parseRepoParam(repo) 19 if err != nil { 20 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest) 21 return 22 } 23 24 ref := r.URL.Query().Get("ref") 25 // ref can be empty (git.Open handles this) 26 27 path := r.URL.Query().Get("path") 28 // path can be empty (defaults to root) 29 30 gr, err := git.Open(repoPath, ref) 31 if err != nil { 32 x.Logger.Error("failed to open git repository", "error", err, "path", repoPath, "ref", ref) 33 writeError(w, xrpcerr.NewXrpcError( 34 xrpcerr.WithTag("RefNotFound"), 35 xrpcerr.WithMessage("repository or ref not found"), 36 ), http.StatusNotFound) 37 return 38 } 39 40 files, err := gr.FileTree(ctx, path) 41 if err != nil { 42 x.Logger.Error("failed to get file tree", "error", err, "path", path) 43 writeError(w, xrpcerr.NewXrpcError( 44 xrpcerr.WithTag("PathNotFound"), 45 xrpcerr.WithMessage("failed to read repository tree"), 46 ), http.StatusNotFound) 47 return 48 } 49 50 // convert NiceTree -> tangled.RepoTree_TreeEntry 51 treeEntries := make([]*tangled.RepoTree_TreeEntry, len(files)) 52 for i, file := range files { 53 entry := &tangled.RepoTree_TreeEntry{ 54 Name: file.Name, 55 Mode: file.Mode, 56 Size: file.Size, 57 Is_file: file.IsFile, 58 Is_subtree: file.IsSubtree, 59 } 60 61 if file.LastCommit != nil { 62 entry.Last_commit = &tangled.RepoTree_LastCommit{ 63 Hash: file.LastCommit.Hash.String(), 64 Message: file.LastCommit.Message, 65 When: file.LastCommit.When.Format(time.RFC3339), 66 } 67 } 68 69 treeEntries[i] = entry 70 } 71 72 var parentPtr *string 73 if path != "" { 74 parentPtr = &path 75 } 76 77 var dotdotPtr *string 78 if path != "" { 79 dotdot := filepath.Dir(path) 80 if dotdot != "." { 81 dotdotPtr = &dotdot 82 } 83 } 84 85 response := tangled.RepoTree_Output{ 86 Ref: ref, 87 Parent: parentPtr, 88 Dotdot: dotdotPtr, 89 Files: treeEntries, 90 } 91 92 w.Header().Set("Content-Type", "application/json") 93 if err := json.NewEncoder(w).Encode(response); err != nil { 94 x.Logger.Error("failed to encode response", "error", err) 95 writeError(w, xrpcerr.NewXrpcError( 96 xrpcerr.WithTag("InternalServerError"), 97 xrpcerr.WithMessage("failed to encode response"), 98 ), http.StatusInternalServerError) 99 return 100 } 101}