diff options
author | Richard Mahn <richmahn@users.noreply.github.com> | 2019-06-08 10:31:11 -0400 |
---|---|---|
committer | Lauris BH <lauris@nix.lv> | 2019-06-08 17:31:11 +0300 |
commit | 8de0b0a3f06fe7879fb014d2624209e0e48455a0 (patch) | |
tree | 55a1413aa439c86749ee0af31d484675e3b4b5cc /routers | |
parent | 23a2ee3510ad1b1e7e89edc526ed394c71a8ba24 (diff) | |
download | gitea-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')
-rw-r--r-- | routers/api/v1/api.go | 2 | ||||
-rw-r--r-- | routers/api/v1/convert/convert.go | 98 | ||||
-rw-r--r-- | routers/api/v1/repo/git_ref.go | 3 | ||||
-rw-r--r-- | routers/api/v1/repo/tag.go | 45 | ||||
-rw-r--r-- | routers/api/v1/swagger/repo.go | 16 |
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 { |