Skip to content

Commit 1f0ba75

Browse files
authored
Merge pull request #14 from gitopia/hariom/commits-api
Implemented commits API with path and pagination
2 parents ce75b21 + 8822788 commit 1f0ba75

6 files changed

Lines changed: 425 additions & 14 deletions

File tree

changelog.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
# Changelog
22

3+
## [v0.5.0] - 2022-02-15
4+
5+
### Features
6+
7+
- Add option to include lastCommit in `/content` API
8+
- API to get repository commits
9+
310
## [v0.4.0] - 2022-02-03
411

512
### Fixes

main.go

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,103 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
542542
return
543543
}
544544

545-
// Repositpry Content
545+
// Repository Commits
546+
if r.Method == "POST" && strings.HasPrefix(r.URL.Path, "/commits") {
547+
defer r.Body.Close()
548+
549+
decoder := json.NewDecoder(r.Body)
550+
var body utils.CommitsRequestBody
551+
err := decoder.Decode(&body)
552+
if err != nil {
553+
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
554+
return
555+
}
556+
557+
blocks := strings.Split(r.URL.Path, "/")
558+
559+
if len(blocks) == 3 {
560+
RepoPath := path.Join(s.config.Dir, fmt.Sprintf("%d.git", body.RepositoryID))
561+
repo, err := git.PlainOpen(RepoPath)
562+
if err != nil {
563+
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
564+
return
565+
}
566+
567+
commitHash := plumbing.NewHash(blocks[2])
568+
commitObject, err := object.GetCommit(repo.Storer, commitHash)
569+
if err != nil {
570+
http.Error(w, err.Error(), http.StatusNotFound)
571+
return
572+
}
573+
574+
commit, err := utils.GrabCommit(*commitObject)
575+
commitResponseJson, err := json.Marshal(commit)
576+
w.Header().Set("Content-Type", "application/json")
577+
w.Header().Set("Access-Control-Allow-Origin", "*")
578+
w.Write(commitResponseJson)
579+
return
580+
}
581+
582+
if len(blocks) != 2 {
583+
http.Error(w, http.StatusText(http.StatusForbidden), http.StatusForbidden)
584+
return
585+
}
586+
587+
if body.InitCommitId == "" {
588+
http.Error(w, http.StatusText(http.StatusBadRequest), http.StatusBadRequest)
589+
return
590+
}
591+
592+
RepoPath := path.Join(s.config.Dir, fmt.Sprintf("%d.git", body.RepositoryID))
593+
repo, err := git.PlainOpen(RepoPath)
594+
if err != nil {
595+
http.Error(w, http.StatusText(http.StatusNotFound), http.StatusNotFound)
596+
return
597+
}
598+
599+
w.Header().Set("Content-Type", "application/json")
600+
w.Header().Set("Access-Control-Allow-Origin", "*")
601+
602+
var commits []*utils.Commit
603+
var pageRes *utils.PageResponse
604+
605+
if body.Path != "" {
606+
commitHash := plumbing.NewHash(body.InitCommitId)
607+
commit, err := object.GetCommit(repo.Storer, commitHash)
608+
if err != nil {
609+
http.Error(w, err.Error(), http.StatusNotFound)
610+
return
611+
}
612+
commitTree, err := commit.Tree()
613+
if err != nil {
614+
http.Error(w, err.Error(), http.StatusNotFound)
615+
return
616+
}
617+
_, err = commitTree.FindEntry(body.Path)
618+
if err != nil {
619+
http.Error(w, err.Error(), http.StatusNotFound)
620+
return
621+
}
622+
}
623+
624+
pageRes, err = utils.PaginateCommitHistoryResponse(RepoPath, repo, body.Pagination, 100, &body, func(commit utils.Commit) error {
625+
commits = append(commits, &commit)
626+
return nil
627+
})
628+
if err != nil {
629+
http.Error(w, err.Error(), http.StatusBadRequest)
630+
}
631+
632+
commitsResponse := utils.CommitsResponse{
633+
Commits: commits,
634+
Pagination: pageRes,
635+
}
636+
commitsResponseJson, err := json.Marshal(commitsResponse)
637+
w.Write(commitsResponseJson)
638+
return
639+
}
640+
641+
// Repository Content
546642
if r.Method == "POST" && strings.HasPrefix(r.URL.Path, "/content") {
547643
defer r.Body.Close()
548644

@@ -608,6 +704,25 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
608704
}
609705
fileContent = append(fileContent, fc)
610706

707+
if body.IncludeLastCommit {
708+
pathCommitId, err := utils.LastCommitForPath(RepoPath, body.RefId, fileContent[0].Path)
709+
if err != nil {
710+
http.Error(w, err.Error(), http.StatusBadRequest)
711+
return
712+
}
713+
pathCommitHash := plumbing.NewHash(pathCommitId)
714+
pathCommitObject, err := object.GetCommit(repo.Storer, pathCommitHash)
715+
if err != nil {
716+
http.Error(w, err.Error(), http.StatusNotFound)
717+
return
718+
}
719+
fileContent[0].LastCommit, err = utils.GrabCommit(*pathCommitObject)
720+
if err != nil {
721+
http.Error(w, err.Error(), http.StatusBadRequest)
722+
return
723+
}
724+
}
725+
611726
contentResponse := utils.ContentResponse{
612727
Content: fileContent,
613728
}
@@ -632,10 +747,43 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
632747
})
633748
if err != nil {
634749
http.Error(w, err.Error(), http.StatusBadRequest)
750+
return
751+
}
752+
753+
if body.IncludeLastCommit {
754+
for i := range treeContents {
755+
pathCommitId, err := utils.LastCommitForPath(RepoPath, body.RefId, treeContents[i].Path)
756+
if err != nil {
757+
http.Error(w, err.Error(), http.StatusBadRequest)
758+
return
759+
}
760+
pathCommitHash := plumbing.NewHash(pathCommitId)
761+
pathCommitObject, err := object.GetCommit(repo.Storer, pathCommitHash)
762+
if err != nil {
763+
http.Error(w, err.Error(), http.StatusNotFound)
764+
return
765+
}
766+
treeContents[i].LastCommit, err = utils.GrabCommit(*pathCommitObject)
767+
if err != nil {
768+
http.Error(w, err.Error(), http.StatusBadRequest)
769+
return
770+
}
771+
}
772+
}
773+
774+
var sortedTREEContents []*utils.Content
775+
var sortedBLOBContents []*utils.Content
776+
for _, tc := range treeContents {
777+
if tc.Type == "TREE" {
778+
sortedTREEContents = append(sortedTREEContents, tc)
779+
} else {
780+
sortedBLOBContents = append(sortedBLOBContents, tc)
781+
}
635782
}
783+
sortedTreeContents := append(sortedTREEContents, sortedBLOBContents...)
636784

637785
contentResponse := utils.ContentResponse{
638-
Content: treeContents,
786+
Content: sortedTreeContents,
639787
Pagination: pageRes,
640788
}
641789
contentResponseJson, err := json.Marshal(contentResponse)

readme.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,3 +41,21 @@ The server will be listening at port `5000`
4141
- `POST` /pull/commits
4242
- `POST` /pull/check
4343
- `POST` /pull/merge
44+
- `POST` /content
45+
```go
46+
type ContentRequestBody struct {
47+
RepositoryID uint64 `json:"repository_id"`
48+
RefId string `json:"ref_id"`
49+
Path string `json:"path"`
50+
Pagination *PageRequest `json:"pagination"`
51+
}
52+
```
53+
- `POST` /commits
54+
```go
55+
type CommitsRequestBody struct {
56+
RepositoryID uint64 `json:"repository_id"`
57+
InitCommitId string `json:"init_commit_id"`
58+
Path string `json:"path"`
59+
Pagination *PageRequest `json:"pagination"`
60+
}
61+
```

0 commit comments

Comments
 (0)