新增:最近提交列表接口

This commit is contained in:
yystopf 2024-01-30 14:48:54 +08:00
parent 8f0e78026d
commit 520306d632
5 changed files with 178 additions and 10 deletions

View File

@ -210,8 +210,7 @@ func serveInstalled(ctx *cli.Context) error {
}
// Set up Chi routes
webRoutes := routers.NormalRoutes()
hat_routers.InitHatRouters(graceful.GetManager().HammerContext(), webRoutes)
webRoutes := hat_routers.NormalRoutes()
err := listen(webRoutes, true)
<-graceful.GetManager().Done()

View File

@ -2,6 +2,10 @@ package git
import (
"bytes"
"encoding/hex"
"fmt"
"io"
"strings"
gitea_git "code.gitea.io/gitea/modules/git"
)
@ -31,3 +35,64 @@ func GetFirstAndLastCommitByPath(repo *gitea_git.Repository, revision, relpath s
return commits[0], commits[len(commits)-1], nil
}
// CommitsByFileAndRange return the commits according revision file and the page
func AllCommitsByFileAndRange(repo *gitea_git.Repository, opts gitea_git.CommitsByFileAndRangeOptions, pageSize int) ([]*gitea_git.Commit, error) {
skip := (opts.Page - 1) * pageSize
stdoutReader, stdoutWriter := io.Pipe()
defer func() {
_ = stdoutReader.Close()
_ = stdoutWriter.Close()
}()
go func() {
stderr := strings.Builder{}
gitCmd := gitea_git.NewCommand(repo.Ctx, "rev-list").
AddOptionFormat("--max-count=%d", pageSize*opts.Page).
AddOptionFormat("--skip=%d", skip)
gitCmd.AddDynamicArguments(opts.Revision)
if opts.Not != "" {
gitCmd.AddOptionValues("--not", opts.Not)
}
gitCmd.AddArguments("--all")
// gitCmd.AddDashesAndList(opts.File)
err := gitCmd.Run(&gitea_git.RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
Stderr: &stderr,
})
if err != nil {
_ = stdoutWriter.CloseWithError(ConcatenateError(err, (&stderr).String()))
} else {
_ = stdoutWriter.Close()
}
}()
commits := []*gitea_git.Commit{}
shaline := [41]byte{}
var sha1 gitea_git.SHA1
for {
n, err := io.ReadFull(stdoutReader, shaline[:])
if err != nil || n < 40 {
if err == io.EOF {
err = nil
}
return commits, err
}
n, err = hex.Decode(sha1[:], shaline[0:40])
if n != 20 {
err = fmt.Errorf("invalid sha %q", string(shaline[:40]))
}
if err != nil {
return nil, err
}
commit, err := repo.GetCommit(sha1.String())
if err != nil {
return nil, err
}
commits = append(commits, commit)
}
}

View File

@ -1,7 +1,6 @@
package hat
import (
gocontext "context"
"fmt"
"net/http"
"strings"
@ -95,7 +94,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.APIC
}
}
func Routers(ctx gocontext.Context) *web.Route {
func Routers() *web.Route {
m := web.NewRoute()
m.Use(securityHeaders())
@ -144,6 +143,7 @@ func Routers(ctx gocontext.Context) *web.Route {
m.Get("/*", repo.GetReadmeContentsByPath)
})
m.Get("/commits_slice", repo.GetAllCommitsSliceByTime)
m.Get("/recent_commits", context.ReferencesGitRepo(), repo.GetRecentCommits)
m.Get("/compare/*", reqRepoReader(unit_model.TypeCode), repo.CompareDiff)
m.Group("/pulls", func() {
m.Group("/{index}", func() {

View File

@ -17,6 +17,7 @@ import (
"code.gitea.io/gitea/services/convert"
"code.gitea.io/gitea/services/gitdiff"
hat_convert "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/convert"
hat_git "code.gitlink.org.cn/Gitlink/gitea_hat.git/modules/git"
)
func GetAllCommitsSliceByTime(ctx *context.APIContext) {
@ -126,6 +127,74 @@ func toResponseCommit(ctx *context.APIContext, repo *repo.Repository, gitRepo *g
}, nil
}
func GetRecentCommits(ctx *context.APIContext) {
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(http.StatusConflict, api.APIError{
Message: "Git Repository is empty",
URL: setting.API.SwaggerURL,
})
return
}
listOptions := utils.GetListOptions(ctx)
if listOptions.Page <= 0 {
listOptions.Page = 1
}
if listOptions.PageSize > setting.Git.CommitsRangeSize {
listOptions.PageSize = setting.Git.CommitsRangeSize
}
var baseCommit *git.Commit
var commitsCountTotal int64
var err error
head, err := ctx.Repo.GitRepo.GetHEADBranch()
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetHeadBranch", err)
return
}
baseCommit, err = ctx.Repo.GitRepo.GetBranchCommit(head.Name)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranchCommit", err)
return
}
commitsCountTotal, err = ctx.Repo.GitRepo.GetAllCommitsCount()
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsCountFiles", err)
return
}
pageCount := int(math.Ceil(float64(commitsCountTotal) / float64(listOptions.PageSize)))
commits, err := hat_git.AllCommitsByFileAndRange(ctx.Repo.GitRepo,
git.CommitsByFileAndRangeOptions{
Revision: baseCommit.ID.String(),
File: ".",
Page: listOptions.Page,
}, listOptions.PageSize)
if err != nil {
ctx.Error(http.StatusInternalServerError, "CommitsByRange", err)
return
}
userCache := make(map[string]*user_model.User)
apiCommits := make([]*api.Commit, len(commits))
for i, commit := range commits {
apiCommits[i], err = convert.ToCommit(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, commit, userCache, convert.ParseCommitOptions(ctx))
if err != nil {
ctx.Error(http.StatusInternalServerError, "ToCommit", err)
return
}
}
ctx.Resp.Header().Set("X-Page", strconv.Itoa(listOptions.Page))
ctx.Resp.Header().Set("X-PerPage", strconv.Itoa(listOptions.PageSize))
ctx.Resp.Header().Set("X-Total", strconv.FormatInt(commitsCountTotal, 10))
ctx.Resp.Header().Set("X-PageCount", strconv.Itoa(pageCount))
ctx.Resp.Header().Set("X-HasMore", strconv.FormatBool(listOptions.Page < pageCount))
ctx.SetLinkHeader(int(commitsCountTotal), listOptions.PageSize)
ctx.Resp.Header().Set("X-Total-Count", fmt.Sprintf("%d", commitsCountTotal))
ctx.JSON(http.StatusOK, apiCommits)
}
func GetFileAllCommits(ctx *context.APIContext) {
if ctx.Repo.Repository.IsEmpty {
ctx.JSON(http.StatusConflict, api.APIError{

View File

@ -10,7 +10,14 @@ import (
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/web"
actions_router "code.gitea.io/gitea/routers/api/actions"
packages_router "code.gitea.io/gitea/routers/api/packages"
apiv1 "code.gitea.io/gitea/routers/api/v1"
"code.gitea.io/gitea/routers/common"
"code.gitea.io/gitea/routers/private"
web_routers "code.gitea.io/gitea/routers/web"
"code.gitlink.org.cn/Gitlink/gitea_hat.git/models/migrations"
api_hat "code.gitlink.org.cn/Gitlink/gitea_hat.git/routers/hat"
hat_pull_service "code.gitlink.org.cn/Gitlink/gitea_hat.git/services/pull"
@ -40,12 +47,6 @@ func GlobalInitInstalled(ctx context.Context) {
}
func InitHatRouters(ctx context.Context, e *web.Route) *web.Route {
e.Mount("/api/hat", api_hat.Routers(ctx))
return e
}
func InitDBEngine(ctx context.Context) (err error) {
log.Info("Beginning hat ORM engine initialization.")
for i := 0; i < setting.Database.DBConnectRetries; i++ {
@ -67,3 +68,37 @@ func InitDBEngine(ctx context.Context) (err error) {
db.HasEngine = true
return nil
}
func NormalRoutes() *web.Route {
_ = templates.HTMLRenderer()
r := web.NewRoute()
r.Use(common.ProtocolMiddlewares()...)
r.Mount("/", web_routers.Routes())
r.Mount("/api/v1", apiv1.Routes())
r.Mount("/api/hat", api_hat.Routers())
r.Mount("/api/internal", private.Routes())
r.Post("/-/fetch-redirect", common.FetchRedirectDelegate)
if setting.Packages.Enabled {
// This implements package support for most package managers
r.Mount("/api/packages", packages_router.CommonRoutes())
// This implements the OCI API (Note this is not preceded by /api but is instead /v2)
r.Mount("/v2", packages_router.ContainerRoutes())
}
if setting.Actions.Enabled {
prefix := "/api/actions"
r.Mount(prefix, actions_router.Routes(prefix))
// TODO: Pipeline api used for runner internal communication with gitea server. but only artifact is used for now.
// In Github, it uses ACTIONS_RUNTIME_URL=https://pipelines.actions.githubusercontent.com/fLgcSHkPGySXeIFrg8W8OBSfeg3b5Fls1A1CwX566g8PayEGlg/
// TODO: this prefix should be generated with a token string with runner ?
prefix = "/api/actions_pipeline"
r.Mount(prefix, actions_router.ArtifactsRoutes(prefix))
}
return r
}