1package xrpc
2
3import (
4 "encoding/json"
5 "net/http"
6 "net/url"
7
8 "tangled.sh/tangled.sh/core/api/tangled"
9 "tangled.sh/tangled.sh/core/knotserver/git"
10 xrpcerr "tangled.sh/tangled.sh/core/xrpc/errors"
11)
12
13func (x *Xrpc) RepoBranch(w http.ResponseWriter, r *http.Request) {
14 repo := r.URL.Query().Get("repo")
15 repoPath, err := x.parseRepoParam(repo)
16 if err != nil {
17 writeError(w, err.(xrpcerr.XrpcError), http.StatusBadRequest)
18 return
19 }
20
21 name := r.URL.Query().Get("name")
22 if name == "" {
23 writeError(w, xrpcerr.NewXrpcError(
24 xrpcerr.WithTag("InvalidRequest"),
25 xrpcerr.WithMessage("missing name parameter"),
26 ), http.StatusBadRequest)
27 return
28 }
29
30 branchName, _ := url.PathUnescape(name)
31
32 gr, err := git.PlainOpen(repoPath)
33 if err != nil {
34 writeError(w, xrpcerr.NewXrpcError(
35 xrpcerr.WithTag("RepoNotFound"),
36 xrpcerr.WithMessage("repository not found"),
37 ), http.StatusNotFound)
38 return
39 }
40
41 ref, err := gr.Branch(branchName)
42 if err != nil {
43 x.Logger.Error("getting branch", "error", err.Error())
44 writeError(w, xrpcerr.NewXrpcError(
45 xrpcerr.WithTag("BranchNotFound"),
46 xrpcerr.WithMessage("branch not found"),
47 ), http.StatusNotFound)
48 return
49 }
50
51 commit, err := gr.Commit(ref.Hash())
52 if err != nil {
53 x.Logger.Error("getting commit object", "error", err.Error())
54 writeError(w, xrpcerr.NewXrpcError(
55 xrpcerr.WithTag("BranchNotFound"),
56 xrpcerr.WithMessage("failed to get commit object"),
57 ), http.StatusInternalServerError)
58 return
59 }
60
61 defaultBranch, err := gr.FindMainBranch()
62 isDefault := false
63 if err != nil {
64 x.Logger.Error("getting default branch", "error", err.Error())
65 } else if defaultBranch == branchName {
66 isDefault = true
67 }
68
69 response := tangled.RepoBranch_Output{
70 Name: ref.Name().Short(),
71 Hash: ref.Hash().String(),
72 ShortHash: &[]string{ref.Hash().String()[:7]}[0],
73 When: commit.Author.When.Format("2006-01-02T15:04:05.000Z"),
74 IsDefault: &isDefault,
75 }
76
77 if commit.Message != "" {
78 response.Message = &commit.Message
79 }
80
81 response.Author = &tangled.RepoBranch_Signature{
82 Name: commit.Author.Name,
83 Email: commit.Author.Email,
84 When: commit.Author.When.Format("2006-01-02T15:04:05.000Z"),
85 }
86
87 w.Header().Set("Content-Type", "application/json")
88 if err := json.NewEncoder(w).Encode(response); err != nil {
89 x.Logger.Error("failed to encode response", "error", err)
90 writeError(w, xrpcerr.NewXrpcError(
91 xrpcerr.WithTag("InternalServerError"),
92 xrpcerr.WithMessage("failed to encode response"),
93 ), http.StatusInternalServerError)
94 return
95 }
96}