From 8a5925b9bdd16446d1335bb34d7de13c331baf43 Mon Sep 17 00:00:00 2001 From: Kasi Date: Fri, 8 Jun 2018 05:33:57 +0100 Subject: [PATCH 1/5] removed seperate router for /repos/search --- routers/api/v1/api.go | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index eec55cac6..466d6b06f 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -368,13 +368,11 @@ func RegisterRoutes(m *macaron.Macaron) { // Repositories m.Post("/org/:org/repos", reqToken(), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) - m.Group("/repos", func() { - m.Get("/search", repo.Search) - }) - m.Combo("/repositories/:id", reqToken()).Get(repo.GetByID) m.Group("/repos", func() { + m.Get("/search", repo.Search) + m.Post("/migrate", reqToken(), bind(auth.MigrateRepoForm{}), repo.Migrate) m.Group("/:username/:reponame", func() { From 347120d900cd2b62aa7f1be6d44de00afabc192f Mon Sep 17 00:00:00 2001 From: Kasi Date: Fri, 8 Jun 2018 14:26:23 +0100 Subject: [PATCH 2/5] Started on Git-Trees api --- routers/api/v1/api.go | 8 ++++ routers/api/v1/repo/tree.go | 89 +++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+) create mode 100644 routers/api/v1/repo/tree.go diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 466d6b06f..d36b1c6d6 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -377,6 +377,11 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/:username/:reponame", func() { m.Combo("").Get(repo.Get).Delete(reqToken(), repo.Delete) + + m.Group("/trees", func() { + m.Combo("/:sha", context.RepoRef()).Get(repo.GetTree) + }) + m.Group("/hooks", func() { m.Combo("").Get(repo.ListHooks). Post(bind(api.CreateHookOption{}), repo.CreateHook) @@ -387,6 +392,9 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/tests", context.RepoRef(), repo.TestHook) }) }, reqToken(), reqRepoWriter()) + + + m.Group("/collaborators", func() { m.Get("", repo.ListCollaborators) m.Combo("/:collaborator").Get(repo.IsCollaborator). diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go new file mode 100644 index 000000000..8ba0e01a5 --- /dev/null +++ b/routers/api/v1/repo/tree.go @@ -0,0 +1,89 @@ +package repo + +import ( + "code.gitea.io/gitea/modules/context" + "fmt" + _"code.gitea.io/git" + "code.gitea.io/gitea/modules/setting" + "strings" +) + +type TreeEntry struct { + Path string `json:"path"` + Mode string `json:"mode"` + Type string `json:"type"` + Size int64 `json:"size,omitempty"` + SHA string `json:"sha"` + URL string `json:"url"` +} + +type Tree struct { + SHA string `json:"sha"` + URL string `json:"url"` + Entries []TreeEntry `json:"tree,omitempty"` + Truncated bool `json:"truncated"` +} + +func GetTree(ctx *context.APIContext) { + sha := ctx.Params("sha") + if len(sha) == 0 { + ctx.Error(400, "sha not provided", nil) + return + } + Temp := GetTreeBySHA(ctx, nil, "", sha, ctx.QueryBool("recursive")) + if Temp != nil { + ctx.JSON(200, Temp) + } else { + ctx.Error(400, "sha invalid", nil) + } + +} + +func GetTreeBySHA(ctx *context.APIContext, tree *Tree, CurrentPath string, sha string, recursive bool) *Tree { + GitTree, err := ctx.Repo.GitRepo.GetTree(sha) + if err != nil { + return tree + } + RepoID := strings.TrimRight(setting.AppURL, "/") + "/api/v1/repos/" + ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name + if tree == nil { + tree = new(Tree) + if GitTree != nil { + tree.SHA = GitTree.ID.String() + tree.URL = RepoID + "/trees/" + tree.SHA; + } + } + if GitTree == nil { + return tree + } + Trees, err := GitTree.ListEntries() + if err != nil { + return tree + } + if len(CurrentPath) != 0 { + CurrentPath += "/" + } + for e := range Trees { + if len(tree.Entries) > 1000 { + tree.Truncated = true + break + } + E_URL := RepoID + if Trees[e].IsDir() { + E_URL += "/trees/" + } else { + E_URL += "/blobs/" + } + tree.Entries = append(tree.Entries, TreeEntry{ + CurrentPath + Trees[e].Name(), + fmt.Sprintf("%06x", Trees[e].Mode()), + string(Trees[e].Type), + Trees[e].Size(), + Trees[e].ID.String(), + E_URL + Trees[e].ID.String()}) + + if recursive && Trees[e].IsDir() { + tree = GetTreeBySHA(ctx, tree, CurrentPath + Trees[e].Name(), Trees[e].ID.String(), recursive) + } + } + return tree +} From b7a13d84dccb8323c9ec0e118aae89604a7c15ad Mon Sep 17 00:00:00 2001 From: Kasi Date: Fri, 8 Jun 2018 16:26:09 +0100 Subject: [PATCH 3/5] Added copyright --- routers/api/v1/repo/tree.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index 8ba0e01a5..f39a302fa 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -1,3 +1,7 @@ +// Copyright 2018 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + package repo import ( From 487758f8f5b9a8d9feb2b81e2032caacc3b29997 Mon Sep 17 00:00:00 2001 From: Kasi Date: Sat, 9 Jun 2018 16:14:33 +0100 Subject: [PATCH 4/5] Optimized recursive part of GetTree though utilizing git ls-tree -r command --- routers/api/v1/repo/tree.go | 79 ++++++++++++++++++++----------------- 1 file changed, 42 insertions(+), 37 deletions(-) diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index f39a302fa..15437d0f5 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -7,9 +7,9 @@ package repo import ( "code.gitea.io/gitea/modules/context" "fmt" - _"code.gitea.io/git" "code.gitea.io/gitea/modules/setting" "strings" + "code.gitea.io/git" ) type TreeEntry struct { @@ -34,59 +34,64 @@ func GetTree(ctx *context.APIContext) { ctx.Error(400, "sha not provided", nil) return } - Temp := GetTreeBySHA(ctx, nil, "", sha, ctx.QueryBool("recursive")) - if Temp != nil { - ctx.JSON(200, Temp) + Tree := GetTreeBySHA(ctx, sha) + if Tree != nil { + ctx.JSON(200, Tree) } else { ctx.Error(400, "sha invalid", nil) } - } -func GetTreeBySHA(ctx *context.APIContext, tree *Tree, CurrentPath string, sha string, recursive bool) *Tree { +func GetTreeBySHA(ctx *context.APIContext, sha string) *Tree { GitTree, err := ctx.Repo.GitRepo.GetTree(sha) - if err != nil { - return tree + if err != nil || GitTree == nil{ + return nil } + tree := new(Tree) RepoID := strings.TrimRight(setting.AppURL, "/") + "/api/v1/repos/" + ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name - if tree == nil { - tree = new(Tree) - if GitTree != nil { - tree.SHA = GitTree.ID.String() - tree.URL = RepoID + "/trees/" + tree.SHA; - } + tree.SHA = GitTree.ID.String() + tree.URL = RepoID + "/trees/" + tree.SHA + var Entries git.Entries + if ctx.QueryBool("recursive") { + Entries, err = GitTree.ListEntriesRecursive() + } else { + Entries, err = GitTree.ListEntries() } - if GitTree == nil { - return tree - } - Trees, err := GitTree.ListEntries() if err != nil { return tree } - if len(CurrentPath) != 0 { - CurrentPath += "/" + RepoIDLen := len(RepoID) + BlobURL := make([]byte, RepoIDLen + 47) + copy(BlobURL[:], RepoID) + copy(BlobURL[RepoIDLen:], "/blobs/") + TreeURL := make([]byte, RepoIDLen + 47) + copy(TreeURL[:], RepoID) + copy(TreeURL[RepoIDLen:], "/trees/") + CopyPos := len(TreeURL) - 40 + + if len(Entries) > 1000 { + tree.Entries = make([]TreeEntry, 1000) + } else { + tree.Entries = make([]TreeEntry, len(Entries)) } - for e := range Trees { - if len(tree.Entries) > 1000 { + for e := range Entries { + if e > 1000 { tree.Truncated = true break } - E_URL := RepoID - if Trees[e].IsDir() { - E_URL += "/trees/" - } else { - E_URL += "/blobs/" - } - tree.Entries = append(tree.Entries, TreeEntry{ - CurrentPath + Trees[e].Name(), - fmt.Sprintf("%06x", Trees[e].Mode()), - string(Trees[e].Type), - Trees[e].Size(), - Trees[e].ID.String(), - E_URL + Trees[e].ID.String()}) - if recursive && Trees[e].IsDir() { - tree = GetTreeBySHA(ctx, tree, CurrentPath + Trees[e].Name(), Trees[e].ID.String(), recursive) + tree.Entries[e].Path = Entries[e].Name() + tree.Entries[e].Mode = fmt.Sprintf("%06x", Entries[e].Mode()) + tree.Entries[e].Type = string(Entries[e].Type) + tree.Entries[e].Size = Entries[e].Size() + tree.Entries[e].SHA = Entries[e].ID.String() + + if Entries[e].IsDir() { + copy(TreeURL[CopyPos:], Entries[e].ID.String()) + tree.Entries[e].URL = string(TreeURL[:]) + } else { + copy(BlobURL[CopyPos:], Entries[e].ID.String()) + tree.Entries[e].URL = string(BlobURL[:]) } } return tree From 3678de006bf52e387e09d9a5f6c5aa1bc030c575 Mon Sep 17 00:00:00 2001 From: Kasi Date: Wed, 13 Jun 2018 11:04:39 +0100 Subject: [PATCH 5/5] Fixed import order, used type from sdk, removed empty lines --- routers/api/v1/api.go | 7 ------- routers/api/v1/repo/tree.go | 30 ++++++++---------------------- 2 files changed, 8 insertions(+), 29 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index d36b1c6d6..a5ae328ac 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -372,16 +372,12 @@ func RegisterRoutes(m *macaron.Macaron) { m.Group("/repos", func() { m.Get("/search", repo.Search) - m.Post("/migrate", reqToken(), bind(auth.MigrateRepoForm{}), repo.Migrate) - m.Group("/:username/:reponame", func() { m.Combo("").Get(repo.Get).Delete(reqToken(), repo.Delete) - m.Group("/trees", func() { m.Combo("/:sha", context.RepoRef()).Get(repo.GetTree) }) - m.Group("/hooks", func() { m.Combo("").Get(repo.ListHooks). Post(bind(api.CreateHookOption{}), repo.CreateHook) @@ -392,9 +388,6 @@ func RegisterRoutes(m *macaron.Macaron) { m.Post("/tests", context.RepoRef(), repo.TestHook) }) }, reqToken(), reqRepoWriter()) - - - m.Group("/collaborators", func() { m.Get("", repo.ListCollaborators) m.Combo("/:collaborator").Get(repo.IsCollaborator). diff --git a/routers/api/v1/repo/tree.go b/routers/api/v1/repo/tree.go index 15437d0f5..627e096d7 100644 --- a/routers/api/v1/repo/tree.go +++ b/routers/api/v1/repo/tree.go @@ -5,29 +5,15 @@ package repo import ( - "code.gitea.io/gitea/modules/context" "fmt" - "code.gitea.io/gitea/modules/setting" "strings" + + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/context" "code.gitea.io/git" + "code.gitea.io/sdk/gitea" ) -type TreeEntry struct { - Path string `json:"path"` - Mode string `json:"mode"` - Type string `json:"type"` - Size int64 `json:"size,omitempty"` - SHA string `json:"sha"` - URL string `json:"url"` -} - -type Tree struct { - SHA string `json:"sha"` - URL string `json:"url"` - Entries []TreeEntry `json:"tree,omitempty"` - Truncated bool `json:"truncated"` -} - func GetTree(ctx *context.APIContext) { sha := ctx.Params("sha") if len(sha) == 0 { @@ -42,12 +28,12 @@ func GetTree(ctx *context.APIContext) { } } -func GetTreeBySHA(ctx *context.APIContext, sha string) *Tree { +func GetTreeBySHA(ctx *context.APIContext, sha string) *gitea.GitTreeResponse { GitTree, err := ctx.Repo.GitRepo.GetTree(sha) if err != nil || GitTree == nil{ return nil } - tree := new(Tree) + tree := new(gitea.GitTreeResponse) RepoID := strings.TrimRight(setting.AppURL, "/") + "/api/v1/repos/" + ctx.Repo.Repository.Owner.Name + "/" + ctx.Repo.Repository.Name tree.SHA = GitTree.ID.String() tree.URL = RepoID + "/trees/" + tree.SHA @@ -70,9 +56,9 @@ func GetTreeBySHA(ctx *context.APIContext, sha string) *Tree { CopyPos := len(TreeURL) - 40 if len(Entries) > 1000 { - tree.Entries = make([]TreeEntry, 1000) + tree.Entries = make([]gitea.GitTreeEntry, 1000) } else { - tree.Entries = make([]TreeEntry, len(Entries)) + tree.Entries = make([]gitea.GitTreeEntry, len(Entries)) } for e := range Entries { if e > 1000 {