forked from Gitlink/gitea_hat
新增:分支列表接口支持搜索参数
This commit is contained in:
parent
b83c3eabc9
commit
a1099096cb
10
go.mod
10
go.mod
|
@ -8,9 +8,14 @@ require (
|
||||||
github.com/caddyserver/certmagic v0.17.2
|
github.com/caddyserver/certmagic v0.17.2
|
||||||
github.com/felixge/fgprof v0.9.3
|
github.com/felixge/fgprof v0.9.3
|
||||||
github.com/go-chi/cors v1.2.1
|
github.com/go-chi/cors v1.2.1
|
||||||
|
github.com/gobwas/glob v0.2.3
|
||||||
github.com/klauspost/cpuid/v2 v2.2.2
|
github.com/klauspost/cpuid/v2 v2.2.2
|
||||||
|
github.com/russross/blackfriday/v2 v2.1.0
|
||||||
github.com/urfave/cli v1.22.10
|
github.com/urfave/cli v1.22.10
|
||||||
|
golang.org/x/net v0.4.0
|
||||||
|
golang.org/x/text v0.5.0
|
||||||
gopkg.in/ini.v1 v1.67.0
|
gopkg.in/ini.v1 v1.67.0
|
||||||
|
xorm.io/builder v0.3.12
|
||||||
xorm.io/xorm v1.3.2
|
xorm.io/xorm v1.3.2
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -93,7 +98,6 @@ require (
|
||||||
github.com/go-ldap/ldap/v3 v3.4.4 // indirect
|
github.com/go-ldap/ldap/v3 v3.4.4 // indirect
|
||||||
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
github.com/go-redis/redis/v8 v8.11.5 // indirect
|
||||||
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
github.com/go-sql-driver/mysql v1.7.0 // indirect
|
||||||
github.com/gobwas/glob v0.2.3 // indirect
|
|
||||||
github.com/goccy/go-json v0.10.0 // indirect
|
github.com/goccy/go-json v0.10.0 // indirect
|
||||||
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
github.com/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // indirect
|
||||||
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 // indirect
|
github.com/gogs/cron v0.0.0-20171120032916-9f6c956d3e14 // indirect
|
||||||
|
@ -172,7 +176,6 @@ require (
|
||||||
github.com/quasoft/websspi v1.1.2 // indirect
|
github.com/quasoft/websspi v1.1.2 // indirect
|
||||||
github.com/rivo/uniseg v0.4.3 // indirect
|
github.com/rivo/uniseg v0.4.3 // indirect
|
||||||
github.com/rs/xid v1.4.0 // indirect
|
github.com/rs/xid v1.4.0 // indirect
|
||||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
|
||||||
github.com/santhosh-tekuri/jsonschema/v5 v5.1.1 // indirect
|
github.com/santhosh-tekuri/jsonschema/v5 v5.1.1 // indirect
|
||||||
github.com/sergi/go-diff v1.2.0 // indirect
|
github.com/sergi/go-diff v1.2.0 // indirect
|
||||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||||
|
@ -201,10 +204,8 @@ require (
|
||||||
go.uber.org/zap v1.24.0 // indirect
|
go.uber.org/zap v1.24.0 // indirect
|
||||||
golang.org/x/crypto v0.4.0 // indirect
|
golang.org/x/crypto v0.4.0 // indirect
|
||||||
golang.org/x/mod v0.7.0 // indirect
|
golang.org/x/mod v0.7.0 // indirect
|
||||||
golang.org/x/net v0.4.0 // indirect
|
|
||||||
golang.org/x/oauth2 v0.3.0 // indirect
|
golang.org/x/oauth2 v0.3.0 // indirect
|
||||||
golang.org/x/sys v0.3.0 // indirect
|
golang.org/x/sys v0.3.0 // indirect
|
||||||
golang.org/x/text v0.5.0 // indirect
|
|
||||||
golang.org/x/time v0.3.0 // indirect
|
golang.org/x/time v0.3.0 // indirect
|
||||||
golang.org/x/tools v0.4.0 // indirect
|
golang.org/x/tools v0.4.0 // indirect
|
||||||
google.golang.org/appengine v1.6.7 // indirect
|
google.golang.org/appengine v1.6.7 // indirect
|
||||||
|
@ -216,5 +217,4 @@ require (
|
||||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
mvdan.cc/xurls/v2 v2.4.0 // indirect
|
mvdan.cc/xurls/v2 v2.4.0 // indirect
|
||||||
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 // indirect
|
strk.kbt.io/projects/go/libravatar v0.0.0-20191008002943-06d1c002b251 // indirect
|
||||||
xorm.io/builder v0.3.12 // indirect
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -0,0 +1,124 @@
|
||||||
|
package git
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
gitea_git "code.gitea.io/gitea/modules/git"
|
||||||
|
)
|
||||||
|
|
||||||
|
func GetSearchBranches(ctx context.Context, repo *gitea_git.Repository, search string, skip, limit int) ([]*gitea_git.Branch, int, error) {
|
||||||
|
brs, countAll, err := callShowSearchRef(ctx, repo.Path, gitea_git.BranchPrefix, "--heads", search, skip, limit)
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
branches := make([]*gitea_git.Branch, len(brs))
|
||||||
|
for i := range brs {
|
||||||
|
branches[i] = &gitea_git.Branch{
|
||||||
|
Name: brs[i],
|
||||||
|
Path: repo.Path,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return branches, countAll, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func callShowSearchRef(ctx context.Context, repoPath, prefix, arg, search string, skip, limit int) (branchNames []string, countAll int, err error) {
|
||||||
|
stdoutReader, stdoutWriter := io.Pipe()
|
||||||
|
defer func() {
|
||||||
|
_ = stdoutReader.Close()
|
||||||
|
_ = stdoutWriter.Close()
|
||||||
|
}()
|
||||||
|
|
||||||
|
go func() {
|
||||||
|
stderrBuilder := &strings.Builder{}
|
||||||
|
err := gitea_git.NewCommand(ctx, "show-ref", gitea_git.CmdArg(arg)).
|
||||||
|
Run(&gitea_git.RunOpts{
|
||||||
|
Dir: repoPath,
|
||||||
|
Stdout: stdoutWriter,
|
||||||
|
Stderr: stderrBuilder,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
if stderrBuilder.Len() == 0 {
|
||||||
|
_ = stdoutWriter.Close()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_ = stdoutWriter.CloseWithError(ConcatenateError(err, stderrBuilder.String()))
|
||||||
|
} else {
|
||||||
|
_ = stdoutWriter.Close()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
i := 0
|
||||||
|
bufReader := bufio.NewReader(stdoutReader)
|
||||||
|
for i < skip {
|
||||||
|
line, isPrefix, err := bufReader.ReadLine()
|
||||||
|
if err == io.EOF {
|
||||||
|
return branchNames, i, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
branchName := strings.TrimPrefix(strings.Split(string(line), " ")[1], prefix)
|
||||||
|
if len(branchName) > 0 {
|
||||||
|
branchName = branchName[:len(branchName)-1]
|
||||||
|
}
|
||||||
|
isSeached := strings.Contains(branchName, search)
|
||||||
|
|
||||||
|
if !isPrefix && isSeached {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for limit == 0 || i < skip+limit {
|
||||||
|
|
||||||
|
branchName, err := bufReader.ReadString('\n')
|
||||||
|
if err == io.EOF {
|
||||||
|
// This shouldn't happen... but we'll tolerate it for the sake of peace
|
||||||
|
return branchNames, i, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, i, err
|
||||||
|
}
|
||||||
|
branchName = strings.TrimPrefix(strings.Split(string(branchName), " ")[1], prefix)
|
||||||
|
if len(branchName) > 0 {
|
||||||
|
branchName = branchName[:len(branchName)-1]
|
||||||
|
}
|
||||||
|
isSeached := strings.Contains(branchName, search)
|
||||||
|
if isSeached {
|
||||||
|
i++
|
||||||
|
branchNames = append(branchNames, branchName)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// count all refs
|
||||||
|
for limit != 0 {
|
||||||
|
line, isPrefix, err := bufReader.ReadLine()
|
||||||
|
if err == io.EOF {
|
||||||
|
return branchNames, i, nil
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return nil, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
branchName := strings.TrimPrefix(strings.Split(string(line), " ")[1], prefix)
|
||||||
|
if len(branchName) > 0 {
|
||||||
|
branchName = branchName[:len(branchName)-1]
|
||||||
|
}
|
||||||
|
isSeached := strings.Contains(branchName, search)
|
||||||
|
|
||||||
|
if !isPrefix && isSeached {
|
||||||
|
i++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return branchNames, i, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func ConcatenateError(err error, stderr string) error {
|
||||||
|
if len(stderr) == 0 {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return fmt.Errorf("%w - %s", err, stderr)
|
||||||
|
}
|
|
@ -71,6 +71,7 @@ func Routers(ctx gocontext.Context) *web.Route {
|
||||||
m.Get("/tag_name_set", context.ReferencesGitRepo(), repo.TagNameSet)
|
m.Get("/tag_name_set", context.ReferencesGitRepo(), repo.TagNameSet)
|
||||||
m.Get("/branch_tag_count", context.ReferencesGitRepo(), repo.BranchTagCount)
|
m.Get("/branch_tag_count", context.ReferencesGitRepo(), repo.BranchTagCount)
|
||||||
m.Group("/branches", func() {
|
m.Group("/branches", func() {
|
||||||
|
m.Get("", repo.ListBranches)
|
||||||
m.Get("/branches_slice", context.ReferencesGitRepo(), repo.ListBranchesSlice)
|
m.Get("/branches_slice", context.ReferencesGitRepo(), repo.ListBranchesSlice)
|
||||||
}, reqRepoReader(unit_model.TypeCode))
|
}, reqRepoReader(unit_model.TypeCode))
|
||||||
m.Group("/commits", func() {
|
m.Group("/commits", func() {
|
||||||
|
|
|
@ -9,12 +9,50 @@ import (
|
||||||
git_model "code.gitea.io/gitea/models/git"
|
git_model "code.gitea.io/gitea/models/git"
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/convert"
|
"code.gitea.io/gitea/modules/convert"
|
||||||
|
gitea_api "code.gitea.io/gitea/modules/structs"
|
||||||
hat_convert "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/convert"
|
hat_convert "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/convert"
|
||||||
|
hat_git "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
|
||||||
|
|
||||||
"code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
|
"code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
|
||||||
|
|
||||||
"code.gitea.io/gitea/routers/api/v1/utils"
|
"code.gitea.io/gitea/routers/api/v1/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func ListBranches(ctx *context.APIContext) {
|
||||||
|
searchName := ctx.Params("name")
|
||||||
|
listOptions := utils.GetListOptions(ctx)
|
||||||
|
skip, _ := listOptions.GetStartEnd()
|
||||||
|
branches, totalNumOfBranches, err := hat_git.GetSearchBranches(ctx, ctx.Repo.GitRepo, searchName, skip, listOptions.PageSize)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
apiBranches := make([]*gitea_api.Branch, len(branches))
|
||||||
|
for i := range branches {
|
||||||
|
c, err := branches[i].GetCommit()
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
branchProtection, err := git_model.GetProtectedBranchBy(ctx, ctx.Repo.Repository.ID, branches[i].Name)
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "GetProtectedBranchBy", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
apiBranches[i], err = convert.ToBranch(ctx.Repo.Repository, branches[i], c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
|
||||||
|
if err != nil {
|
||||||
|
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize)
|
||||||
|
ctx.RespHeader().Set("X-Total-Count", fmt.Sprintf("%d", totalNumOfBranches))
|
||||||
|
ctx.RespHeader().Set("Access-Control-Expose-Headers", "X-Total-Count, Link")
|
||||||
|
ctx.JSON(http.StatusOK, &apiBranches)
|
||||||
|
}
|
||||||
|
|
||||||
func ListBranchesSlice(ctx *context.APIContext) {
|
func ListBranchesSlice(ctx *context.APIContext) {
|
||||||
listOptions := utils.GetListOptions(ctx)
|
listOptions := utils.GetListOptions(ctx)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue