mirror of
https://github.com/go-gitea/gitea.git
synced 2026-10-05 16:47:51 +02:00
Merge remote-tracking branch 'upstream/main' into limit-repo-size
This commit is contained in:
commit
1765ea329b
445 files changed
+11672
-11535
No files matched your search
+11
-6
@@ -291,7 +291,7 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
|
||||
}
|
||||
|
||||
task.LogFilename = logFileName(job.Run.Repo.FullName(), task.ID)
|
||||
if _, err := e.ID(task.ID).Cols("log_filename").Update(task); err != nil {
|
||||
if err := UpdateTask(ctx, task, "log_filename"); err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
@@ -367,9 +367,18 @@ func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionT
|
||||
return nil, util.ErrNotExist
|
||||
}
|
||||
|
||||
if task.Status.IsDone() {
|
||||
// the state is final, do nothing
|
||||
return task, nil
|
||||
}
|
||||
|
||||
// state.Result is not unspecified means the task is finished
|
||||
if state.Result != runnerv1.Result_RESULT_UNSPECIFIED {
|
||||
task.Status = Status(state.Result)
|
||||
task.Stopped = timeutil.TimeStamp(state.StoppedAt.AsTime().Unix())
|
||||
if err := UpdateTask(ctx, task, "status", "stopped"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if _, err := UpdateRunJob(ctx, &ActionRunJob{
|
||||
ID: task.JobID,
|
||||
Status: task.Status,
|
||||
@@ -379,10 +388,6 @@ func UpdateTaskByState(ctx context.Context, state *runnerv1.TaskState) (*ActionT
|
||||
}
|
||||
}
|
||||
|
||||
if _, err := e.ID(task.ID).Update(task); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := task.LoadAttributes(ctx); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -440,7 +445,7 @@ func StopTask(ctx context.Context, taskID int64, status Status) error {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := e.ID(task.ID).Update(task); err != nil {
|
||||
if err := UpdateTask(ctx, task, "status", "stopped"); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -494,12 +494,27 @@ func activityQueryCondition(opts GetFeedsOptions) (builder.Cond, error) {
|
||||
).From("`user`"),
|
||||
))
|
||||
} else if !opts.Actor.IsAdmin {
|
||||
cond = cond.And(builder.In("act_user_id",
|
||||
builder.Select("`user`.id").Where(
|
||||
builder.Eq{"keep_activity_private": false}.
|
||||
And(builder.In("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))).
|
||||
Or(builder.Eq{"id": opts.Actor.ID}).From("`user`"),
|
||||
))
|
||||
uidCond := builder.Select("`user`.id").From("`user`").Where(
|
||||
builder.Eq{"keep_activity_private": false}.
|
||||
And(builder.In("visibility", structs.VisibleTypePublic, structs.VisibleTypeLimited))).
|
||||
Or(builder.Eq{"id": opts.Actor.ID})
|
||||
|
||||
if opts.RequestedUser != nil {
|
||||
if opts.RequestedUser.IsOrganization() {
|
||||
// An organization can always see the activities whose `act_user_id` is the same as its id.
|
||||
uidCond = uidCond.Or(builder.Eq{"id": opts.RequestedUser.ID})
|
||||
} else {
|
||||
// A user can always see the activities of the organizations to which the user belongs.
|
||||
uidCond = uidCond.Or(
|
||||
builder.Eq{"type": user_model.UserTypeOrganization}.
|
||||
And(builder.In("`user`.id", builder.Select("org_id").
|
||||
Where(builder.Eq{"uid": opts.RequestedUser.ID}).
|
||||
From("team_user"))),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
cond = cond.And(builder.In("act_user_id", uidCond))
|
||||
}
|
||||
|
||||
// check readable repositories by doer/actor
|
||||
|
||||
+1
-32
@@ -17,8 +17,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// Task represents a task
|
||||
@@ -35,7 +33,7 @@ type Task struct {
|
||||
StartTime timeutil.TimeStamp
|
||||
EndTime timeutil.TimeStamp
|
||||
PayloadContent string `xorm:"TEXT"`
|
||||
Message string `xorm:"TEXT"` // if task failed, saved the error reason
|
||||
Message string `xorm:"TEXT"` // if task failed, saved the error reason, it could be a JSON string of TranslatableMessage or a plain message
|
||||
Created timeutil.TimeStamp `xorm:"created"`
|
||||
}
|
||||
|
||||
@@ -185,14 +183,6 @@ func GetMigratingTask(repoID int64) (*Task, error) {
|
||||
return &task, nil
|
||||
}
|
||||
|
||||
// HasFinishedMigratingTask returns if a finished migration task exists for the repo.
|
||||
func HasFinishedMigratingTask(repoID int64) (bool, error) {
|
||||
return db.GetEngine(db.DefaultContext).
|
||||
Where("repo_id=? AND type=? AND status=?", repoID, structs.TaskTypeMigrateRepo, structs.TaskStatusFinished).
|
||||
Table("task").
|
||||
Exist()
|
||||
}
|
||||
|
||||
// GetMigratingTaskByID returns the migrating task by repo's id
|
||||
func GetMigratingTaskByID(id, doerID int64) (*Task, *migration.MigrateOptions, error) {
|
||||
task := Task{
|
||||
@@ -214,27 +204,6 @@ func GetMigratingTaskByID(id, doerID int64) (*Task, *migration.MigrateOptions, e
|
||||
return &task, &opts, nil
|
||||
}
|
||||
|
||||
// FindTaskOptions find all tasks
|
||||
type FindTaskOptions struct {
|
||||
Status int
|
||||
}
|
||||
|
||||
// ToConds generates conditions for database operation.
|
||||
func (opts FindTaskOptions) ToConds() builder.Cond {
|
||||
cond := builder.NewCond()
|
||||
if opts.Status >= 0 {
|
||||
cond = cond.And(builder.Eq{"status": opts.Status})
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
// FindTasks find all tasks
|
||||
func FindTasks(opts FindTaskOptions) ([]*Task, error) {
|
||||
tasks := make([]*Task, 0, 10)
|
||||
err := db.GetEngine(db.DefaultContext).Where(opts.ToConds()).Find(&tasks)
|
||||
return tasks, err
|
||||
}
|
||||
|
||||
// CreateTask creates a task on database
|
||||
func CreateTask(task *Task) error {
|
||||
return db.Insert(db.DefaultContext, task)
|
||||
|
||||
@@ -8,14 +8,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.InitProviderAndLoadCommonSettingsForTest()
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", ".."),
|
||||
|
||||
@@ -8,14 +8,8 @@ import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.InitProviderAndLoadCommonSettingsForTest()
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
unittest.MainTest(m, &unittest.TestOptions{
|
||||
GiteaRootPath: filepath.Join("..", ".."),
|
||||
|
||||
@@ -108,3 +108,31 @@
|
||||
is_prerelease: false
|
||||
is_tag: false
|
||||
created_unix: 946684803
|
||||
|
||||
- id: 9
|
||||
repo_id: 57
|
||||
publisher_id: 2
|
||||
tag_name: "non-existing-target-branch"
|
||||
lower_tag_name: "non-existing-target-branch"
|
||||
target: "non-existing"
|
||||
title: "non-existing-target-branch"
|
||||
sha1: "cef06e48f2642cd0dc9597b4bea09f4b3f74aad6"
|
||||
num_commits: 5
|
||||
is_draft: false
|
||||
is_prerelease: false
|
||||
is_tag: false
|
||||
created_unix: 946684803
|
||||
|
||||
- id: 10
|
||||
repo_id: 57
|
||||
publisher_id: 2
|
||||
tag_name: "empty-target-branch"
|
||||
lower_tag_name: "empty-target-branch"
|
||||
target: ""
|
||||
title: "empty-target-branch"
|
||||
sha1: "cef06e48f2642cd0dc9597b4bea09f4b3f74aad6"
|
||||
num_commits: 5
|
||||
is_draft: false
|
||||
is_prerelease: false
|
||||
is_tag: false
|
||||
created_unix: 946684803
|
||||
@@ -159,33 +159,6 @@ func (l *Label) BelongsToRepo() bool {
|
||||
return l.RepoID > 0
|
||||
}
|
||||
|
||||
// Get color as RGB values in 0..255 range
|
||||
func (l *Label) ColorRGB() (float64, float64, float64, error) {
|
||||
color, err := strconv.ParseUint(l.Color[1:], 16, 64)
|
||||
if err != nil {
|
||||
return 0, 0, 0, err
|
||||
}
|
||||
|
||||
r := float64(uint8(0xFF & (uint32(color) >> 16)))
|
||||
g := float64(uint8(0xFF & (uint32(color) >> 8)))
|
||||
b := float64(uint8(0xFF & uint32(color)))
|
||||
return r, g, b, nil
|
||||
}
|
||||
|
||||
// Determine if label text should be light or dark to be readable on background color
|
||||
func (l *Label) UseLightTextColor() bool {
|
||||
if strings.HasPrefix(l.Color, "#") {
|
||||
if r, g, b, err := l.ColorRGB(); err == nil {
|
||||
// Perceived brightness from: https://www.w3.org/TR/AERT/#color-contrast
|
||||
// In the future WCAG 3 APCA may be a better solution
|
||||
brightness := (0.299*r + 0.587*g + 0.114*b) / 255
|
||||
return brightness < 0.35
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// Return scope substring of label name, or empty string if none exists
|
||||
func (l *Label) ExclusiveScope() string {
|
||||
if !l.Exclusive {
|
||||
|
||||
@@ -22,15 +22,6 @@ func TestLabel_CalOpenIssues(t *testing.T) {
|
||||
assert.EqualValues(t, 2, label.NumOpenIssues)
|
||||
}
|
||||
|
||||
func TestLabel_TextColor(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
|
||||
assert.False(t, label.UseLightTextColor())
|
||||
|
||||
label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
|
||||
assert.True(t, label.UseLightTextColor())
|
||||
}
|
||||
|
||||
func TestLabel_ExclusiveScope(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 7})
|
||||
|
||||
@@ -9,7 +9,6 @@ import (
|
||||
|
||||
issues_model "code.gitea.io/gitea/models/issues"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
_ "code.gitea.io/gitea/models"
|
||||
_ "code.gitea.io/gitea/models/repo"
|
||||
@@ -18,11 +17,6 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.InitProviderAndLoadCommonSettingsForTest()
|
||||
}
|
||||
|
||||
func TestFixturesAreConsistent(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
unittest.CheckConsistencyFor(t,
|
||||
|
||||
@@ -433,6 +433,10 @@ func (pr *PullRequest) GetGitRefName() string {
|
||||
return fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index)
|
||||
}
|
||||
|
||||
func (pr *PullRequest) GetGitHeadBranchRefName() string {
|
||||
return fmt.Sprintf("%s%s", git.BranchPrefix, pr.HeadBranch)
|
||||
}
|
||||
|
||||
// IsChecking returns true if this pull request is still checking conflict.
|
||||
func (pr *PullRequest) IsChecking() bool {
|
||||
return pr.Status == PullRequestStatusChecking
|
||||
|
||||
@@ -51,16 +51,11 @@ func listPullRequestStatement(baseRepoID int64, opts *PullRequestsOptions) (*xor
|
||||
}
|
||||
|
||||
// GetUnmergedPullRequestsByHeadInfo returns all pull requests that are open and has not been merged
|
||||
// by given head information (repo and branch).
|
||||
// arg `includeClosed` controls whether the SQL returns closed PRs
|
||||
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string, includeClosed bool) ([]*PullRequest, error) {
|
||||
func GetUnmergedPullRequestsByHeadInfo(repoID int64, branch string) ([]*PullRequest, error) {
|
||||
prs := make([]*PullRequest, 0, 2)
|
||||
sess := db.GetEngine(db.DefaultContext).
|
||||
Join("INNER", "issue", "issue.id = pull_request.issue_id").
|
||||
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND flow = ?", repoID, branch, false, PullRequestFlowGithub)
|
||||
if !includeClosed {
|
||||
sess.Where("issue.is_closed = ?", false)
|
||||
}
|
||||
Where("head_repo_id = ? AND head_branch = ? AND has_merged = ? AND issue.is_closed = ? AND flow = ?", repoID, branch, false, false, PullRequestFlowGithub)
|
||||
return prs, sess.Find(&prs)
|
||||
}
|
||||
|
||||
@@ -74,7 +69,7 @@ func CanMaintainerWriteToBranch(p access_model.Permission, branch string, user *
|
||||
return false
|
||||
}
|
||||
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch, false)
|
||||
prs, err := GetUnmergedPullRequestsByHeadInfo(p.Units[0].RepoID, branch)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
|
||||
func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2", false)
|
||||
prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(1, "branch2")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, prs, 1)
|
||||
for _, pr := range prs {
|
||||
|
||||
@@ -189,6 +189,20 @@ func (r *Review) LoadAttributes(ctx context.Context) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Review) HTMLTypeColorName() string {
|
||||
switch r.Type {
|
||||
case ReviewTypeApprove:
|
||||
return "green"
|
||||
case ReviewTypeComment:
|
||||
return "grey"
|
||||
case ReviewTypeReject:
|
||||
return "red"
|
||||
case ReviewTypeRequest:
|
||||
return "yellow"
|
||||
}
|
||||
return "grey"
|
||||
}
|
||||
|
||||
// GetReviewByID returns the review by the given ID
|
||||
func GetReviewByID(ctx context.Context, id int64) (*Review, error) {
|
||||
review := new(Review)
|
||||
|
||||
@@ -11,18 +11,12 @@ import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
_ "code.gitea.io/gitea/models/system"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func init() {
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.InitProviderAndLoadCommonSettingsForTest()
|
||||
}
|
||||
|
||||
// TestFixturesAreConsistent assert that test fixtures are consistent
|
||||
func TestFixturesAreConsistent(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
@@ -1,180 +0,0 @@
|
||||
// Copyright 2019 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package base
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/queue"
|
||||
)
|
||||
|
||||
var (
|
||||
prefix string
|
||||
slowTest = 10 * time.Second
|
||||
slowFlush = 5 * time.Second
|
||||
)
|
||||
|
||||
// TestLogger is a logger which will write to the testing log
|
||||
type TestLogger struct {
|
||||
log.WriterLogger
|
||||
}
|
||||
|
||||
var writerCloser = &testLoggerWriterCloser{}
|
||||
|
||||
type testLoggerWriterCloser struct {
|
||||
sync.RWMutex
|
||||
t []*testing.TB
|
||||
}
|
||||
|
||||
func (w *testLoggerWriterCloser) setT(t *testing.TB) {
|
||||
w.Lock()
|
||||
w.t = append(w.t, t)
|
||||
w.Unlock()
|
||||
}
|
||||
|
||||
func (w *testLoggerWriterCloser) Write(p []byte) (int, error) {
|
||||
w.RLock()
|
||||
var t *testing.TB
|
||||
if len(w.t) > 0 {
|
||||
t = w.t[len(w.t)-1]
|
||||
}
|
||||
w.RUnlock()
|
||||
if t != nil && *t != nil {
|
||||
if len(p) > 0 && p[len(p)-1] == '\n' {
|
||||
p = p[:len(p)-1]
|
||||
}
|
||||
|
||||
defer func() {
|
||||
err := recover()
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
var errString string
|
||||
errErr, ok := err.(error)
|
||||
if ok {
|
||||
errString = errErr.Error()
|
||||
} else {
|
||||
errString, ok = err.(string)
|
||||
}
|
||||
if !ok {
|
||||
panic(err)
|
||||
}
|
||||
if !strings.HasPrefix(errString, "Log in goroutine after ") {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
(*t).Log(string(p))
|
||||
return len(p), nil
|
||||
}
|
||||
return len(p), nil
|
||||
}
|
||||
|
||||
func (w *testLoggerWriterCloser) Close() error {
|
||||
w.Lock()
|
||||
if len(w.t) > 0 {
|
||||
w.t = w.t[:len(w.t)-1]
|
||||
}
|
||||
w.Unlock()
|
||||
return nil
|
||||
}
|
||||
|
||||
// PrintCurrentTest prints the current test to os.Stdout
|
||||
func PrintCurrentTest(t testing.TB, skip ...int) func() {
|
||||
start := time.Now()
|
||||
actualSkip := 1
|
||||
if len(skip) > 0 {
|
||||
actualSkip = skip[0]
|
||||
}
|
||||
_, filename, line, _ := runtime.Caller(actualSkip)
|
||||
|
||||
if log.CanColorStdout {
|
||||
fmt.Fprintf(os.Stdout, "=== %s (%s:%d)\n", fmt.Formatter(log.NewColoredValue(t.Name())), strings.TrimPrefix(filename, prefix), line)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, "=== %s (%s:%d)\n", t.Name(), strings.TrimPrefix(filename, prefix), line)
|
||||
}
|
||||
writerCloser.setT(&t)
|
||||
return func() {
|
||||
took := time.Since(start)
|
||||
if took > slowTest {
|
||||
if log.CanColorStdout {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgYellow)), fmt.Formatter(log.NewColoredValue(took, log.Bold, log.FgYellow)))
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s is a slow test (took %v)\n", t.Name(), took)
|
||||
}
|
||||
}
|
||||
timer := time.AfterFunc(slowFlush, func() {
|
||||
if log.CanColorStdout {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgRed)), slowFlush)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s ... still flushing after %v ...\n", t.Name(), slowFlush)
|
||||
}
|
||||
})
|
||||
if err := queue.GetManager().FlushAll(context.Background(), -1); err != nil {
|
||||
t.Errorf("Flushing queues failed with error %v", err)
|
||||
}
|
||||
timer.Stop()
|
||||
flushTook := time.Since(start) - took
|
||||
if flushTook > slowFlush {
|
||||
if log.CanColorStdout {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s had a slow clean-up flush (took %v)\n", fmt.Formatter(log.NewColoredValue(t.Name(), log.Bold, log.FgRed)), fmt.Formatter(log.NewColoredValue(flushTook, log.Bold, log.FgRed)))
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, "+++ %s had a slow clean-up flush (took %v)\n", t.Name(), flushTook)
|
||||
}
|
||||
}
|
||||
_ = writerCloser.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Printf takes a format and args and prints the string to os.Stdout
|
||||
func Printf(format string, args ...interface{}) {
|
||||
if log.CanColorStdout {
|
||||
for i := 0; i < len(args); i++ {
|
||||
args[i] = log.NewColoredValue(args[i])
|
||||
}
|
||||
}
|
||||
fmt.Fprintf(os.Stdout, "\t"+format, args...)
|
||||
}
|
||||
|
||||
// NewTestLogger creates a TestLogger as a log.LoggerProvider
|
||||
func NewTestLogger() log.LoggerProvider {
|
||||
logger := &TestLogger{}
|
||||
logger.Colorize = log.CanColorStdout
|
||||
logger.Level = log.TRACE
|
||||
return logger
|
||||
}
|
||||
|
||||
// Init inits connection writer with json config.
|
||||
// json config only need key "level".
|
||||
func (log *TestLogger) Init(config string) error {
|
||||
err := json.Unmarshal([]byte(config), log)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
log.NewWriterLogger(writerCloser)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Flush when log should be flushed
|
||||
func (log *TestLogger) Flush() {
|
||||
}
|
||||
|
||||
// ReleaseReopen does nothing
|
||||
func (log *TestLogger) ReleaseReopen() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetName returns the default name for this implementation
|
||||
func (log *TestLogger) GetName() string {
|
||||
return "test"
|
||||
}
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
"path"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
@@ -19,6 +18,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/testlogger"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"xorm.io/xorm"
|
||||
@@ -32,7 +32,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
|
||||
t.Helper()
|
||||
ourSkip := 2
|
||||
ourSkip += skip
|
||||
deferFn := PrintCurrentTest(t, ourSkip)
|
||||
deferFn := testlogger.PrintCurrentTest(t, ourSkip)
|
||||
assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
|
||||
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "tests/gitea-repositories-meta"), setting.RepoRootPath))
|
||||
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
|
||||
@@ -110,9 +110,7 @@ func PrepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
|
||||
}
|
||||
|
||||
func MainTest(m *testing.M) {
|
||||
log.Register("test", NewTestLogger)
|
||||
_, filename, _, _ := runtime.Caller(0)
|
||||
prefix = strings.TrimSuffix(filename, "tests/testlogger.go")
|
||||
log.Register("test", testlogger.NewTestLogger)
|
||||
|
||||
giteaRoot := base.SetupGiteaRoot()
|
||||
if giteaRoot == "" {
|
||||
@@ -150,7 +148,7 @@ func MainTest(m *testing.M) {
|
||||
setting.AppDataPath = tmpDataPath
|
||||
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
setting.InitProviderAndLoadCommonSettingsForTest()
|
||||
unittest.InitSettings()
|
||||
if err = git.InitFull(context.Background()); err != nil {
|
||||
fmt.Printf("Unable to InitFull: %v\n", err)
|
||||
os.Exit(1)
|
||||
|
||||
@@ -25,6 +25,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/packages/nuget"
|
||||
"code.gitea.io/gitea/modules/packages/pub"
|
||||
"code.gitea.io/gitea/modules/packages/pypi"
|
||||
"code.gitea.io/gitea/modules/packages/rpm"
|
||||
"code.gitea.io/gitea/modules/packages/rubygems"
|
||||
"code.gitea.io/gitea/modules/packages/swift"
|
||||
"code.gitea.io/gitea/modules/packages/vagrant"
|
||||
@@ -163,6 +164,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
|
||||
metadata = &pub.Metadata{}
|
||||
case TypePyPI:
|
||||
metadata = &pypi.Metadata{}
|
||||
case TypeRpm:
|
||||
metadata = &rpm.VersionMetadata{}
|
||||
case TypeRubyGems:
|
||||
metadata = &rubygems.Metadata{}
|
||||
case TypeSwift:
|
||||
|
||||
@@ -44,6 +44,7 @@ const (
|
||||
TypeNuGet Type = "nuget"
|
||||
TypePub Type = "pub"
|
||||
TypePyPI Type = "pypi"
|
||||
TypeRpm Type = "rpm"
|
||||
TypeRubyGems Type = "rubygems"
|
||||
TypeSwift Type = "swift"
|
||||
TypeVagrant Type = "vagrant"
|
||||
@@ -64,6 +65,7 @@ var TypeList = []Type{
|
||||
TypeNuGet,
|
||||
TypePub,
|
||||
TypePyPI,
|
||||
TypeRpm,
|
||||
TypeRubyGems,
|
||||
TypeSwift,
|
||||
TypeVagrant,
|
||||
@@ -100,6 +102,8 @@ func (pt Type) Name() string {
|
||||
return "Pub"
|
||||
case TypePyPI:
|
||||
return "PyPI"
|
||||
case TypeRpm:
|
||||
return "RPM"
|
||||
case TypeRubyGems:
|
||||
return "RubyGems"
|
||||
case TypeSwift:
|
||||
@@ -141,6 +145,8 @@ func (pt Type) SVGName() string {
|
||||
return "gitea-pub"
|
||||
case TypePyPI:
|
||||
return "gitea-python"
|
||||
case TypeRpm:
|
||||
return "gitea-rpm"
|
||||
case TypeRubyGems:
|
||||
return "gitea-rubygems"
|
||||
case TypeSwift:
|
||||
|
||||
@@ -118,7 +118,7 @@ func DeleteFileByID(ctx context.Context, fileID int64) error {
|
||||
// PackageFileSearchOptions are options for SearchXXX methods
|
||||
type PackageFileSearchOptions struct {
|
||||
OwnerID int64
|
||||
PackageType string
|
||||
PackageType Type
|
||||
VersionID int64
|
||||
Query string
|
||||
CompositeKey string
|
||||
|
||||
+3
-4
@@ -35,12 +35,11 @@ import (
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ItemsPerPage maximum items per page in forks, watchers and stars of a repo
|
||||
var ItemsPerPage = 40
|
||||
|
||||
// Init initialize model
|
||||
func Init(ctx context.Context) error {
|
||||
unit.LoadUnitConfig()
|
||||
if err := unit.LoadUnitConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
return system_model.Init(ctx)
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,7 @@ type Release struct {
|
||||
OriginalAuthorID int64 `xorm:"index"`
|
||||
LowerTagName string
|
||||
Target string
|
||||
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
|
||||
Title string
|
||||
Sha1 string `xorm:"VARCHAR(40)"`
|
||||
NumCommits int64
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package repo
|
||||
|
||||
import "code.gitea.io/gitea/models/db"
|
||||
|
||||
// SearchOrderByMap represents all possible search order
|
||||
var SearchOrderByMap = map[string]map[string]db.SearchOrderBy{
|
||||
"asc": {
|
||||
"alpha": db.SearchOrderByAlphabetically,
|
||||
"created": db.SearchOrderByOldest,
|
||||
"updated": db.SearchOrderByLeastUpdated,
|
||||
"size": db.SearchOrderBySize,
|
||||
"id": db.SearchOrderByID,
|
||||
},
|
||||
"desc": {
|
||||
"alpha": db.SearchOrderByAlphabeticallyReverse,
|
||||
"created": db.SearchOrderByNewest,
|
||||
"updated": db.SearchOrderByRecentUpdated,
|
||||
"size": db.SearchOrderBySizeReverse,
|
||||
"id": db.SearchOrderByIDReverse,
|
||||
},
|
||||
}
|
||||
+11
-36
@@ -4,6 +4,7 @@
|
||||
package unit
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -106,12 +107,6 @@ var (
|
||||
TypeExternalTracker,
|
||||
}
|
||||
|
||||
// MustRepoUnits contains the units could not be disabled currently
|
||||
MustRepoUnits = []Type{
|
||||
TypeCode,
|
||||
TypeReleases,
|
||||
}
|
||||
|
||||
// DisabledRepoUnits contains the units that have been globally disabled
|
||||
DisabledRepoUnits = []Type{}
|
||||
)
|
||||
@@ -122,18 +117,13 @@ func validateDefaultRepoUnits(defaultUnits, settingDefaultUnits []Type) []Type {
|
||||
|
||||
// Use setting if not empty
|
||||
if len(settingDefaultUnits) > 0 {
|
||||
// MustRepoUnits required as default
|
||||
units = make([]Type, len(MustRepoUnits))
|
||||
copy(units, MustRepoUnits)
|
||||
units = make([]Type, 0, len(settingDefaultUnits))
|
||||
for _, settingUnit := range settingDefaultUnits {
|
||||
if !settingUnit.CanBeDefault() {
|
||||
log.Warn("Not allowed as default unit: %s", settingUnit.String())
|
||||
continue
|
||||
}
|
||||
// MustRepoUnits already added
|
||||
if settingUnit.CanDisable() {
|
||||
units = append(units, settingUnit)
|
||||
}
|
||||
units = append(units, settingUnit)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -150,30 +140,30 @@ func validateDefaultRepoUnits(defaultUnits, settingDefaultUnits []Type) []Type {
|
||||
}
|
||||
|
||||
// LoadUnitConfig load units from settings
|
||||
func LoadUnitConfig() {
|
||||
func LoadUnitConfig() error {
|
||||
var invalidKeys []string
|
||||
DisabledRepoUnits, invalidKeys = FindUnitTypes(setting.Repository.DisabledRepoUnits...)
|
||||
if len(invalidKeys) > 0 {
|
||||
log.Warn("Invalid keys in disabled repo units: %s", strings.Join(invalidKeys, ", "))
|
||||
}
|
||||
// Check that must units are not disabled
|
||||
for i, disabledU := range DisabledRepoUnits {
|
||||
if !disabledU.CanDisable() {
|
||||
log.Warn("Not allowed to global disable unit %s", disabledU.String())
|
||||
DisabledRepoUnits = append(DisabledRepoUnits[:i], DisabledRepoUnits[i+1:]...)
|
||||
}
|
||||
}
|
||||
|
||||
setDefaultRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultRepoUnits...)
|
||||
if len(invalidKeys) > 0 {
|
||||
log.Warn("Invalid keys in default repo units: %s", strings.Join(invalidKeys, ", "))
|
||||
}
|
||||
DefaultRepoUnits = validateDefaultRepoUnits(DefaultRepoUnits, setDefaultRepoUnits)
|
||||
if len(DefaultRepoUnits) == 0 {
|
||||
return errors.New("no default repository units found")
|
||||
}
|
||||
setDefaultForkRepoUnits, invalidKeys := FindUnitTypes(setting.Repository.DefaultForkRepoUnits...)
|
||||
if len(invalidKeys) > 0 {
|
||||
log.Warn("Invalid keys in default fork repo units: %s", strings.Join(invalidKeys, ", "))
|
||||
}
|
||||
DefaultForkRepoUnits = validateDefaultRepoUnits(DefaultForkRepoUnits, setDefaultForkRepoUnits)
|
||||
if len(DefaultForkRepoUnits) == 0 {
|
||||
return errors.New("no default fork repository units found")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// UnitGlobalDisabled checks if unit type is global disabled
|
||||
@@ -186,16 +176,6 @@ func (u Type) UnitGlobalDisabled() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// CanDisable checks if this unit type can be disabled.
|
||||
func (u *Type) CanDisable() bool {
|
||||
for _, mu := range MustRepoUnits {
|
||||
if *u == mu {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// CanBeDefault checks if the unit type can be a default repo unit
|
||||
func (u *Type) CanBeDefault() bool {
|
||||
for _, nadU := range NotAllowedDefaultRepoUnits {
|
||||
@@ -216,11 +196,6 @@ type Unit struct {
|
||||
MaxAccessMode perm.AccessMode // The max access mode of the unit. i.e. Read means this unit can only be read.
|
||||
}
|
||||
|
||||
// CanDisable returns if this unit could be disabled.
|
||||
func (u *Unit) CanDisable() bool {
|
||||
return u.Type.CanDisable()
|
||||
}
|
||||
|
||||
// IsLessThan compares order of two units
|
||||
func (u Unit) IsLessThan(unit Unit) bool {
|
||||
if (u.Type == TypeExternalTracker || u.Type == TypeExternalWiki) && unit.Type != TypeExternalTracker && unit.Type != TypeExternalWiki {
|
||||
|
||||
+59
-17
@@ -12,42 +12,84 @@ import (
|
||||
)
|
||||
|
||||
func TestLoadUnitConfig(t *testing.T) {
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
|
||||
DisabledRepoUnits = disabledRepoUnits
|
||||
DefaultRepoUnits = defaultRepoUnits
|
||||
DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
|
||||
setting.Repository.DisabledRepoUnits = disabledRepoUnits
|
||||
setting.Repository.DefaultRepoUnits = defaultRepoUnits
|
||||
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
|
||||
|
||||
t.Run("regular", func(t *testing.T) {
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
|
||||
DisabledRepoUnits = disabledRepoUnits
|
||||
DefaultRepoUnits = defaultRepoUnits
|
||||
DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
|
||||
setting.Repository.DisabledRepoUnits = disabledRepoUnits
|
||||
setting.Repository.DefaultRepoUnits = defaultRepoUnits
|
||||
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
|
||||
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.issues"}
|
||||
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls"}
|
||||
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases"}
|
||||
LoadUnitConfig()
|
||||
assert.NoError(t, LoadUnitConfig())
|
||||
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
|
||||
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
|
||||
})
|
||||
t.Run("invalid", func(t *testing.T) {
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
|
||||
DisabledRepoUnits = disabledRepoUnits
|
||||
DefaultRepoUnits = defaultRepoUnits
|
||||
DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
|
||||
setting.Repository.DisabledRepoUnits = disabledRepoUnits
|
||||
setting.Repository.DefaultRepoUnits = defaultRepoUnits
|
||||
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
|
||||
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "invalid.1"}
|
||||
setting.Repository.DefaultRepoUnits = []string{"repo.code", "invalid.2", "repo.releases", "repo.issues", "repo.pulls"}
|
||||
setting.Repository.DefaultForkRepoUnits = []string{"invalid.3", "repo.releases"}
|
||||
LoadUnitConfig()
|
||||
assert.NoError(t, LoadUnitConfig())
|
||||
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
|
||||
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
|
||||
})
|
||||
t.Run("duplicate", func(t *testing.T) {
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
|
||||
DisabledRepoUnits = disabledRepoUnits
|
||||
DefaultRepoUnits = defaultRepoUnits
|
||||
DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
|
||||
setting.Repository.DisabledRepoUnits = disabledRepoUnits
|
||||
setting.Repository.DefaultRepoUnits = defaultRepoUnits
|
||||
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
|
||||
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.issues"}
|
||||
setting.Repository.DefaultRepoUnits = []string{"repo.code", "repo.releases", "repo.issues", "repo.pulls", "repo.code"}
|
||||
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases", "repo.releases"}
|
||||
LoadUnitConfig()
|
||||
assert.NoError(t, LoadUnitConfig())
|
||||
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases, TypePullRequests}, DefaultRepoUnits)
|
||||
assert.Equal(t, []Type{TypeCode, TypeReleases}, DefaultForkRepoUnits)
|
||||
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
|
||||
})
|
||||
t.Run("empty_default", func(t *testing.T) {
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []Type) {
|
||||
DisabledRepoUnits = disabledRepoUnits
|
||||
DefaultRepoUnits = defaultRepoUnits
|
||||
DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(DisabledRepoUnits, DefaultRepoUnits, DefaultForkRepoUnits)
|
||||
defer func(disabledRepoUnits, defaultRepoUnits, defaultForkRepoUnits []string) {
|
||||
setting.Repository.DisabledRepoUnits = disabledRepoUnits
|
||||
setting.Repository.DefaultRepoUnits = defaultRepoUnits
|
||||
setting.Repository.DefaultForkRepoUnits = defaultForkRepoUnits
|
||||
}(setting.Repository.DisabledRepoUnits, setting.Repository.DefaultRepoUnits, setting.Repository.DefaultForkRepoUnits)
|
||||
|
||||
setting.Repository.DisabledRepoUnits = []string{"repo.issues", "repo.issues"}
|
||||
setting.Repository.DefaultRepoUnits = []string{}
|
||||
setting.Repository.DefaultForkRepoUnits = []string{"repo.releases", "repo.releases"}
|
||||
assert.NoError(t, LoadUnitConfig())
|
||||
assert.Equal(t, []Type{TypeIssues}, DisabledRepoUnits)
|
||||
assert.ElementsMatch(t, []Type{TypeCode, TypePullRequests, TypeReleases, TypeWiki, TypePackages, TypeProjects}, DefaultRepoUnits)
|
||||
assert.Equal(t, []Type{TypeReleases}, DefaultForkRepoUnits)
|
||||
})
|
||||
}
|
||||
@@ -6,12 +6,15 @@ package unittest
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
system_model "code.gitea.io/gitea/models/system"
|
||||
"code.gitea.io/gitea/modules/auth/password/hash"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -39,6 +42,22 @@ func fatalTestError(fmtStr string, args ...interface{}) {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// InitSettings initializes config provider and load common setttings for tests
|
||||
func InitSettings(extraConfigs ...string) {
|
||||
setting.Init(&setting.Options{
|
||||
AllowEmpty: true,
|
||||
ExtraConfig: strings.Join(extraConfigs, "\n"),
|
||||
})
|
||||
|
||||
if err := setting.PrepareAppDataPath(); err != nil {
|
||||
log.Fatalf("Can not prepare APP_DATA_PATH: %v", err)
|
||||
}
|
||||
// register the dummy hash algorithm function used in the test fixtures
|
||||
_ = hash.Register("dummy", hash.NewDummyHasher)
|
||||
|
||||
setting.PasswordHashAlgo, _ = hash.SetDefaultPasswordHashAlgorithm("dummy")
|
||||
}
|
||||
|
||||
// TestOptions represents test options
|
||||
type TestOptions struct {
|
||||
GiteaRootPath string
|
||||
@@ -50,6 +69,9 @@ type TestOptions struct {
|
||||
// MainTest a reusable TestMain(..) function for unit tests that need to use a
|
||||
// test database. Creates the test database, and sets necessary settings.
|
||||
func MainTest(m *testing.M, testOpts *TestOptions) {
|
||||
setting.SetCustomPathAndConf("", "", "")
|
||||
InitSettings()
|
||||
|
||||
var err error
|
||||
|
||||
giteaRoot = testOpts.GiteaRootPath
|
||||
@@ -180,6 +202,9 @@ type FixturesOptions struct {
|
||||
func CreateTestEngine(opts FixturesOptions) error {
|
||||
x, err := xorm.NewEngine("sqlite3", "file::memory:?cache=shared&_txlock=immediate")
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "unknown driver") {
|
||||
return fmt.Errorf(`sqlite3 requires: import _ "github.com/mattn/go-sqlite3" or -tags sqlite,sqlite_unlock_notify%s%w`, "\n", err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
x.SetMapper(names.GonicMapper{})
|
||||
|
||||
+21
-20
@@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
gouuid "github.com/google/uuid"
|
||||
@@ -40,15 +41,14 @@ type HookResponse struct {
|
||||
|
||||
// HookTask represents a hook task.
|
||||
type HookTask struct {
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
HookID int64 `xorm:"index"`
|
||||
UUID string `xorm:"unique"`
|
||||
api.Payloader `xorm:"-"`
|
||||
PayloadContent string `xorm:"LONGTEXT"`
|
||||
EventType webhook_module.HookEventType
|
||||
IsDelivered bool
|
||||
Delivered int64
|
||||
DeliveredString string `xorm:"-"`
|
||||
ID int64 `xorm:"pk autoincr"`
|
||||
HookID int64 `xorm:"index"`
|
||||
UUID string `xorm:"unique"`
|
||||
api.Payloader `xorm:"-"`
|
||||
PayloadContent string `xorm:"LONGTEXT"`
|
||||
EventType webhook_module.HookEventType
|
||||
IsDelivered bool
|
||||
Delivered timeutil.TimeStampNano
|
||||
|
||||
// History info.
|
||||
IsSucceed bool
|
||||
@@ -75,8 +75,6 @@ func (t *HookTask) BeforeUpdate() {
|
||||
|
||||
// AfterLoad updates the webhook object upon setting a column
|
||||
func (t *HookTask) AfterLoad() {
|
||||
t.DeliveredString = time.Unix(0, t.Delivered).Format("2006-01-02 15:04:05 MST")
|
||||
|
||||
if len(t.RequestContent) == 0 {
|
||||
return
|
||||
}
|
||||
@@ -115,12 +113,17 @@ func HookTasks(hookID int64, page int) ([]*HookTask, error) {
|
||||
// CreateHookTask creates a new hook task,
|
||||
// it handles conversion from Payload to PayloadContent.
|
||||
func CreateHookTask(ctx context.Context, t *HookTask) (*HookTask, error) {
|
||||
data, err := t.Payloader.JSONPayload()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.UUID = gouuid.New().String()
|
||||
t.PayloadContent = string(data)
|
||||
if t.Payloader != nil {
|
||||
data, err := t.Payloader.JSONPayload()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.PayloadContent = string(data)
|
||||
}
|
||||
if t.Delivered == 0 {
|
||||
t.Delivered = timeutil.TimeStampNanoNow()
|
||||
}
|
||||
return t, db.Insert(ctx, t)
|
||||
}
|
||||
|
||||
@@ -161,13 +164,11 @@ func ReplayHookTask(ctx context.Context, hookID int64, uuid string) (*HookTask,
|
||||
}
|
||||
}
|
||||
|
||||
newTask := &HookTask{
|
||||
UUID: gouuid.New().String(),
|
||||
return CreateHookTask(ctx, &HookTask{
|
||||
HookID: task.HookID,
|
||||
PayloadContent: task.PayloadContent,
|
||||
EventType: task.EventType,
|
||||
}
|
||||
return newTask, db.Insert(ctx, newTask)
|
||||
})
|
||||
}
|
||||
|
||||
// FindUndeliveredHookTaskIDs will find the next 100 undelivered hook tasks with ID greater than the provided lowerID
|
||||
|
||||
@@ -12,6 +12,7 @@ import (
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
webhook_module "code.gitea.io/gitea/modules/webhook"
|
||||
|
||||
@@ -222,7 +223,6 @@ func TestUpdateHookTask(t *testing.T) {
|
||||
|
||||
hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1})
|
||||
hook.PayloadContent = "new payload content"
|
||||
hook.DeliveredString = "new delivered string"
|
||||
hook.IsDelivered = true
|
||||
unittest.AssertNotExistsBean(t, hook)
|
||||
assert.NoError(t, UpdateHookTask(hook))
|
||||
@@ -235,7 +235,7 @@ func TestCleanupHookTaskTable_PerWebhook_DeletesDelivered(t *testing.T) {
|
||||
HookID: 3,
|
||||
Payloader: &api.PushPayload{},
|
||||
IsDelivered: true,
|
||||
Delivered: time.Now().UnixNano(),
|
||||
Delivered: timeutil.TimeStampNanoNow(),
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
_, err := CreateHookTask(db.DefaultContext, hookTask)
|
||||
@@ -268,7 +268,7 @@ func TestCleanupHookTaskTable_PerWebhook_LeavesMostRecentTask(t *testing.T) {
|
||||
HookID: 4,
|
||||
Payloader: &api.PushPayload{},
|
||||
IsDelivered: true,
|
||||
Delivered: time.Now().UnixNano(),
|
||||
Delivered: timeutil.TimeStampNanoNow(),
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
_, err := CreateHookTask(db.DefaultContext, hookTask)
|
||||
@@ -285,7 +285,7 @@ func TestCleanupHookTaskTable_OlderThan_DeletesDelivered(t *testing.T) {
|
||||
HookID: 3,
|
||||
Payloader: &api.PushPayload{},
|
||||
IsDelivered: true,
|
||||
Delivered: time.Now().AddDate(0, 0, -8).UnixNano(),
|
||||
Delivered: timeutil.TimeStampNano(time.Now().AddDate(0, 0, -8).UnixNano()),
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
_, err := CreateHookTask(db.DefaultContext, hookTask)
|
||||
@@ -318,7 +318,7 @@ func TestCleanupHookTaskTable_OlderThan_LeavesTaskEarlierThanAgeToDelete(t *test
|
||||
HookID: 4,
|
||||
Payloader: &api.PushPayload{},
|
||||
IsDelivered: true,
|
||||
Delivered: time.Now().AddDate(0, 0, -6).UnixNano(),
|
||||
Delivered: timeutil.TimeStampNano(time.Now().AddDate(0, 0, -6).UnixNano()),
|
||||
}
|
||||
unittest.AssertNotExistsBean(t, hookTask)
|
||||
_, err := CreateHookTask(db.DefaultContext, hookTask)
|
||||
|
||||
Reference in new issue
Block a user