forked from Gitlink/gitea_hat
新增:最近提交列表接口
This commit is contained in:
parent
8f0e78026d
commit
520306d632
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue