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/felixge/fgprof v0.9.3
|
||||
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/russross/blackfriday/v2 v2.1.0
|
||||
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
|
||||
xorm.io/builder v0.3.12
|
||||
xorm.io/xorm v1.3.2
|
||||
)
|
||||
|
||||
|
@ -93,7 +98,6 @@ require (
|
|||
github.com/go-ldap/ldap/v3 v3.4.4 // indirect
|
||||
github.com/go-redis/redis/v8 v8.11.5 // 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/gogs/chardet v0.0.0-20211120154057-b7413eaefb8f // 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/rivo/uniseg v0.4.3 // 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/sergi/go-diff v1.2.0 // indirect
|
||||
github.com/sirupsen/logrus v1.9.0 // indirect
|
||||
|
@ -201,10 +204,8 @@ require (
|
|||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/crypto v0.4.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/sys v0.3.0 // indirect
|
||||
golang.org/x/text v0.5.0 // indirect
|
||||
golang.org/x/time v0.3.0 // indirect
|
||||
golang.org/x/tools v0.4.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
|
@ -216,5 +217,4 @@ require (
|
|||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
mvdan.cc/xurls/v2 v2.4.0 // 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("/branch_tag_count", context.ReferencesGitRepo(), repo.BranchTagCount)
|
||||
m.Group("/branches", func() {
|
||||
m.Get("", repo.ListBranches)
|
||||
m.Get("/branches_slice", context.ReferencesGitRepo(), repo.ListBranchesSlice)
|
||||
}, reqRepoReader(unit_model.TypeCode))
|
||||
m.Group("/commits", func() {
|
||||
|
|
|
@ -9,12 +9,50 @@ import (
|
|||
git_model "code.gitea.io/gitea/models/git"
|
||||
"code.gitea.io/gitea/modules/context"
|
||||
"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_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"
|
||||
)
|
||||
|
||||
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) {
|
||||
listOptions := utils.GetListOptions(ctx)
|
||||
|
||||
|
|
Loading…
Reference in New Issue