summaryrefslogtreecommitdiffstats
path: root/routers/api
diff options
context:
space:
mode:
authorRichard Mahn <richmahn@users.noreply.github.com>2019-06-08 10:31:11 -0400
committerLauris BH <lauris@nix.lv>2019-06-08 17:31:11 +0300
commit8de0b0a3f06fe7879fb014d2624209e0e48455a0 (patch)
tree55a1413aa439c86749ee0af31d484675e3b4b5cc /routers/api
parent23a2ee3510ad1b1e7e89edc526ed394c71a8ba24 (diff)
downloadgitea-8de0b0a3f06fe7879fb014d2624209e0e48455a0.tar.gz
gitea-8de0b0a3f06fe7879fb014d2624209e0e48455a0.zip
Fixes #2738 - Adds the /git/tags API endpoint (#7138)
* Fixes #2738 - /git/tags API * proper URLs * Adds function comments * Updates swagger * Removes newline from tag message * Removes trailing newline from commit message * Adds integration test * Removed debugging * Adds tests * Fixes bug where multiple tags of same commit show wrong tag name * Fix formatting * Removes unused varaible * Fix to annotated tag function names and response * Update modules/git/repo_tag.go Co-Authored-By: Lauris BH <lauris@nix.lv> * Uses TagPrefix * Changes per review, better error handling for getting tag and commit IDs * Fix to getting commit ID * Fix to getting commit ID * Fix to getting commit ID * Fix to getting commit ID
Diffstat (limited to 'routers/api')
-rw-r--r--routers/api/v1/api.go2
-rw-r--r--routers/api/v1/convert/convert.go98
-rw-r--r--routers/api/v1/repo/git_ref.go3
-rw-r--r--routers/api/v1/repo/tag.go45
-rw-r--r--routers/api/v1/swagger/repo.go16
5 files changed, 133 insertions, 31 deletions
diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go
index c1561200cd..2268c1be38 100644
--- a/routers/api/v1/api.go
+++ b/routers/api/v1/api.go
@@ -751,6 +751,7 @@ func RegisterRoutes(m *macaron.Macaron) {
Post(reqToken(), bind(api.CreateStatusOption{}), repo.NewCommitStatus)
}, reqRepoReader(models.UnitTypeCode))
m.Group("/commits/:ref", func() {
+ // TODO: Add m.Get("") for single commit (https://developer.github.com/v3/repos/commits/#get-a-single-commit)
m.Get("/status", repo.GetCombinedCommitStatusByRef)
m.Get("/statuses", repo.GetCommitStatusesByRef)
}, reqRepoReader(models.UnitTypeCode))
@@ -762,6 +763,7 @@ func RegisterRoutes(m *macaron.Macaron) {
m.Get("/refs/*", repo.GetGitRefs)
m.Get("/trees/:sha", context.RepoRef(), repo.GetTree)
m.Get("/blobs/:sha", context.RepoRef(), repo.GetBlob)
+ m.Get("/tags/:sha", context.RepoRef(), repo.GetTag)
}, reqRepoReader(models.UnitTypeCode))
m.Group("/contents", func() {
m.Get("/*", repo.GetFileContents)
diff --git a/routers/api/v1/convert/convert.go b/routers/api/v1/convert/convert.go
index ba61c7e46c..a982cb8d37 100644
--- a/routers/api/v1/convert/convert.go
+++ b/routers/api/v1/convert/convert.go
@@ -6,6 +6,7 @@ package convert
import (
"fmt"
+ "time"
"code.gitea.io/gitea/models"
"code.gitea.io/gitea/modules/git"
@@ -26,7 +27,7 @@ func ToEmail(email *models.EmailAddress) *api.Email {
}
}
-// ToBranch convert a commit and branch to an api.Branch
+// ToBranch convert a git.Commit and git.Branch to an api.Branch
func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit) *api.Branch {
return &api.Branch{
Name: b.Name,
@@ -34,23 +35,18 @@ func ToBranch(repo *models.Repository, b *git.Branch, c *git.Commit) *api.Branch
}
}
-// ToTag convert a tag to an api.Tag
+// ToTag convert a git.Tag to an api.Tag
func ToTag(repo *models.Repository, t *git.Tag) *api.Tag {
return &api.Tag{
- Name: t.Name,
- Commit: struct {
- SHA string `json:"sha"`
- URL string `json:"url"`
- }{
- SHA: t.ID.String(),
- URL: util.URLJoin(repo.Link(), "commit", t.ID.String()),
- },
- ZipballURL: util.URLJoin(repo.Link(), "archive", t.Name+".zip"),
- TarballURL: util.URLJoin(repo.Link(), "archive", t.Name+".tar.gz"),
+ Name: t.Name,
+ ID: t.ID.String(),
+ Commit: ToCommitMeta(repo, t),
+ ZipballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".zip"),
+ TarballURL: util.URLJoin(repo.HTMLURL(), "archive", t.Name+".tar.gz"),
}
}
-// ToCommit convert a commit to api.PayloadCommit
+// ToCommit convert a git.Commit to api.PayloadCommit
func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit {
authorUsername := ""
if author, err := models.GetUserByEmail(c.Author.Email); err == nil {
@@ -66,17 +62,10 @@ func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit {
log.Error("GetUserByEmail: %v", err)
}
- verif := models.ParseCommitWithSignature(c)
- var signature, payload string
- if c.Signature != nil {
- signature = c.Signature.Signature
- payload = c.Signature.Payload
- }
-
return &api.PayloadCommit{
ID: c.ID.String(),
Message: c.Message(),
- URL: util.URLJoin(repo.Link(), "commit", c.ID.String()),
+ URL: util.URLJoin(repo.HTMLURL(), "commit", c.ID.String()),
Author: &api.PayloadUser{
Name: c.Author.Name,
Email: c.Author.Email,
@@ -87,13 +76,24 @@ func ToCommit(repo *models.Repository, c *git.Commit) *api.PayloadCommit {
Email: c.Committer.Email,
UserName: committerUsername,
},
- Timestamp: c.Author.When,
- Verification: &api.PayloadCommitVerification{
- Verified: verif.Verified,
- Reason: verif.Reason,
- Signature: signature,
- Payload: payload,
- },
+ Timestamp: c.Author.When,
+ Verification: ToVerification(c),
+ }
+}
+
+// ToVerification convert a git.Commit.Signature to an api.PayloadCommitVerification
+func ToVerification(c *git.Commit) *api.PayloadCommitVerification {
+ verif := models.ParseCommitWithSignature(c)
+ var signature, payload string
+ if c.Signature != nil {
+ signature = c.Signature.Signature
+ payload = c.Signature.Payload
+ }
+ return &api.PayloadCommitVerification{
+ Verified: verif.Verified,
+ Reason: verif.Reason,
+ Signature: signature,
+ Payload: payload,
}
}
@@ -242,3 +242,45 @@ func ToUser(user *models.User, signed, admin bool) *api.User {
}
return result
}
+
+// ToAnnotatedTag convert git.Tag to api.AnnotatedTag
+func ToAnnotatedTag(repo *models.Repository, t *git.Tag, c *git.Commit) *api.AnnotatedTag {
+ return &api.AnnotatedTag{
+ Tag: t.Name,
+ SHA: t.ID.String(),
+ Object: ToAnnotatedTagObject(repo, c),
+ Message: t.Message,
+ URL: util.URLJoin(repo.APIURL(), "git/tags", t.ID.String()),
+ Tagger: ToCommitUser(t.Tagger),
+ Verification: ToVerification(c),
+ }
+}
+
+// ToAnnotatedTagObject convert a git.Commit to an api.AnnotatedTagObject
+func ToAnnotatedTagObject(repo *models.Repository, commit *git.Commit) *api.AnnotatedTagObject {
+ return &api.AnnotatedTagObject{
+ SHA: commit.ID.String(),
+ Type: string(git.ObjectCommit),
+ URL: util.URLJoin(repo.APIURL(), "git/commits", commit.ID.String()),
+ }
+}
+
+// ToCommitUser convert a git.Signature to an api.CommitUser
+func ToCommitUser(sig *git.Signature) *api.CommitUser {
+ return &api.CommitUser{
+ Identity: api.Identity{
+ Name: sig.Name,
+ Email: sig.Email,
+ },
+ Date: sig.When.UTC().Format(time.RFC3339),
+ }
+}
+
+// ToCommitMeta convert a git.Tag to an api.CommitMeta
+func ToCommitMeta(repo *models.Repository, tag *git.Tag) *api.CommitMeta {
+ return &api.CommitMeta{
+ SHA: tag.ID.String(),
+ // TODO: Add the /commits API endpoint and use it here (https://developer.github.com/v3/repos/commits/#get-a-single-commit)
+ URL: util.URLJoin(repo.APIURL(), "git/commits", tag.ID.String()),
+ }
+}
diff --git a/routers/api/v1/repo/git_ref.go b/routers/api/v1/repo/git_ref.go
index 2ec8749058..e15f699a1d 100644
--- a/routers/api/v1/repo/git_ref.go
+++ b/routers/api/v1/repo/git_ref.go
@@ -100,8 +100,7 @@ func getGitRefsInternal(ctx *context.APIContext, filter string) {
Object: &api.GitObject{
SHA: refs[i].Object.String(),
Type: refs[i].Type,
- // TODO: Add commit/tag info URL
- //URL: ctx.Repo.Repository.APIURL() + "/git/" + refs[i].Type + "s/" + refs[i].Object.String(),
+ URL: ctx.Repo.Repository.APIURL() + "/git/" + refs[i].Type + "s/" + refs[i].Object.String(),
},
}
}
diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go
index dd1b5aa7c1..ecf580e1b0 100644
--- a/routers/api/v1/repo/tag.go
+++ b/routers/api/v1/repo/tag.go
@@ -7,6 +7,7 @@ package repo
import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/routers/api/v1/convert"
+ "net/http"
api "code.gitea.io/gitea/modules/structs"
)
@@ -45,3 +46,47 @@ func ListTags(ctx *context.APIContext) {
ctx.JSON(200, &apiTags)
}
+
+// GetTag get the tag of a repository.
+func GetTag(ctx *context.APIContext) {
+ // swagger:operation GET /repos/{owner}/{repo}/git/tags/{sha} repository GetTag
+ // ---
+ // summary: Gets the tag of a repository.
+ // produces:
+ // - application/json
+ // parameters:
+ // - name: owner
+ // in: path
+ // description: owner of the repo
+ // type: string
+ // required: true
+ // - name: repo
+ // in: path
+ // description: name of the repo
+ // type: string
+ // required: true
+ // - name: sha
+ // in: path
+ // description: sha of the tag
+ // type: string
+ // required: true
+ // responses:
+ // "200":
+ // "$ref": "#/responses/AnnotatedTag"
+
+ sha := ctx.Params("sha")
+ if len(sha) == 0 {
+ ctx.Error(http.StatusBadRequest, "", "SHA not provided")
+ return
+ }
+
+ if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil {
+ ctx.Error(http.StatusBadRequest, "GetTag", err)
+ } else {
+ commit, err := tag.Commit()
+ if err != nil {
+ ctx.Error(http.StatusBadRequest, "GetTag", err)
+ }
+ ctx.JSON(http.StatusOK, convert.ToAnnotatedTag(ctx.Repo.Repository, tag, commit))
+ }
+}
diff --git a/routers/api/v1/swagger/repo.go b/routers/api/v1/swagger/repo.go
index e7df0b8f71..25354b3d66 100644
--- a/routers/api/v1/swagger/repo.go
+++ b/routers/api/v1/swagger/repo.go
@@ -38,11 +38,25 @@ type swaggerResponseBranchList struct {
// TagList
// swagger:response TagList
-type swaggerReponseTagList struct {
+type swaggerResponseTagList struct {
// in:body
Body []api.Tag `json:"body"`
}
+// Tag
+// swagger:response Tag
+type swaggerResponseTag struct {
+ // in:body
+ Body api.Tag `json:"body"`
+}
+
+// AnnotatedTag
+// swagger:response AnnotatedTag
+type swaggerResponseAnnotatedTag struct {
+ // in:body
+ Body api.AnnotatedTag `json:"body"`
+}
+
// Reference
// swagger:response Reference
type swaggerResponseReference struct {