Compare commits

..

No commits in common. "7a5af25592003ddc3017fcd7b822a3e02fc40ef6" and "067b0c2664d127c552ccdfd264257caca4907a77" have entirely different histories.

46 changed files with 253 additions and 596 deletions

View File

@ -10,12 +10,9 @@ tasks:
- name: Run backend - name: Run backend
command: | command: |
gp sync-await setup gp sync-await setup
if [ ! -f custom/conf/app.ini ]
then
mkdir -p custom/conf/ mkdir -p custom/conf/
echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini echo -e "[server]\nROOT_URL=$(gp url 3000)/" > custom/conf/app.ini
echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini echo -e "\n[database]\nDB_TYPE = sqlite3\nPATH = $GITPOD_REPO_ROOT/data/gitea.db" >> custom/conf/app.ini
fi
export TAGS="sqlite sqlite_unlock_notify" export TAGS="sqlite sqlite_unlock_notify"
make watch-backend make watch-backend
- name: Run frontend - name: Run frontend

View File

@ -11,7 +11,6 @@ import (
"net/url" "net/url"
"os" "os"
"os/exec" "os/exec"
"path/filepath"
"regexp" "regexp"
"strconv" "strconv"
"strings" "strings"
@ -291,21 +290,17 @@ func runServ(c *cli.Context) error {
return nil return nil
} }
// Special handle for Windows.
if setting.IsWindows {
verb = strings.Replace(verb, "-", " ", 1)
}
var gitcmd *exec.Cmd var gitcmd *exec.Cmd
gitBinPath := filepath.Dir(git.GitExecutable) // e.g. /usr/bin verbs := strings.Split(verb, " ")
gitBinVerb := filepath.Join(gitBinPath, verb) // e.g. /usr/bin/git-upload-pack if len(verbs) == 2 {
if _, err := os.Stat(gitBinVerb); err != nil { gitcmd = exec.CommandContext(ctx, verbs[0], verbs[1], repoPath)
// if the command "git-upload-pack" doesn't exist, try to split "git-upload-pack" to use the sub-command with git } else {
// ps: Windows only has "git.exe" in the bin path, so Windows always uses this way gitcmd = exec.CommandContext(ctx, verb, repoPath)
verbFields := strings.SplitN(verb, "-", 2)
if len(verbFields) == 2 {
// use git binary with the sub-command part: "C:\...\bin\git.exe", "upload-pack", ...
gitcmd = exec.CommandContext(ctx, git.GitExecutable, verbFields[1], repoPath)
}
}
if gitcmd == nil {
// by default, use the verb (it has been checked above by allowedCommands)
gitcmd = exec.CommandContext(ctx, gitBinVerb, repoPath)
} }
process.SetSysProcAttribute(gitcmd) process.SetSysProcAttribute(gitcmd)

View File

@ -192,7 +192,6 @@ func InsertRun(ctx context.Context, run *ActionRun, jobs []*jobparser.SingleWork
if len(needs) > 0 || run.NeedApproval { if len(needs) > 0 || run.NeedApproval {
status = StatusBlocked status = StatusBlocked
} }
job.Name, _ = util.SplitStringAtByteN(job.Name, 255)
runJobs = append(runJobs, &ActionRunJob{ runJobs = append(runJobs, &ActionRunJob{
RunID: run.ID, RunID: run.ID,
RepoID: run.RepoID, RepoID: run.RepoID,

View File

@ -298,9 +298,8 @@ func CreateTaskForRunner(ctx context.Context, runner *ActionRunner) (*ActionTask
if len(workflowJob.Steps) > 0 { if len(workflowJob.Steps) > 0 {
steps := make([]*ActionTaskStep, len(workflowJob.Steps)) steps := make([]*ActionTaskStep, len(workflowJob.Steps))
for i, v := range workflowJob.Steps { for i, v := range workflowJob.Steps {
name, _ := util.SplitStringAtByteN(v.String(), 255)
steps[i] = &ActionTaskStep{ steps[i] = &ActionTaskStep{
Name: name, Name: v.String(),
TaskID: task.ID, TaskID: task.ID,
Index: int64(i), Index: int64(i),
RepoID: task.RepoID, RepoID: task.RepoID,

View File

@ -312,7 +312,7 @@ func CheckGitVersionAtLeast(atLeast string) error {
} }
func configSet(key, value string) error { func configSet(key, value string) error {
stdout, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) stdout, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
if err != nil && !err.IsExitCode(1) { if err != nil && !err.IsExitCode(1) {
return fmt.Errorf("failed to get git config %s, err: %w", key, err) return fmt.Errorf("failed to get git config %s, err: %w", key, err)
} }
@ -331,7 +331,7 @@ func configSet(key, value string) error {
} }
func configSetNonExist(key, value string) error { func configSetNonExist(key, value string) error {
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) _, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
if err == nil { if err == nil {
// already exist // already exist
return nil return nil
@ -349,7 +349,7 @@ func configSetNonExist(key, value string) error {
} }
func configAddNonExist(key, value string) error { func configAddNonExist(key, value string) error {
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil) _, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)
if err == nil { if err == nil {
// already exist // already exist
return nil return nil
@ -366,7 +366,7 @@ func configAddNonExist(key, value string) error {
} }
func configUnsetAll(key, value string) error { func configUnsetAll(key, value string) error {
_, _, err := NewCommand(DefaultContext, "config", "--global", "--get").AddDynamicArguments(key).RunStdString(nil) _, _, err := NewCommand(DefaultContext, "config", "--get").AddDynamicArguments(key).RunStdString(nil)
if err == nil { if err == nil {
// exist, need to remove // exist, need to remove
_, _, err = NewCommand(DefaultContext, "config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil) _, _, err = NewCommand(DefaultContext, "config", "--global", "--unset-all").AddDynamicArguments(key, regexp.QuoteMeta(value)).RunStdString(nil)

View File

@ -124,10 +124,7 @@ func (q *ChannelQueue) Shutdown() {
log.Trace("ChannelQueue: %s Flushing", q.name) log.Trace("ChannelQueue: %s Flushing", q.name)
// We can't use Cleanup here because that will close the channel // We can't use Cleanup here because that will close the channel
if err := q.FlushWithContext(q.terminateCtx); err != nil { if err := q.FlushWithContext(q.terminateCtx); err != nil {
count := atomic.LoadInt64(&q.numInQueue)
if count > 0 {
log.Warn("ChannelQueue: %s Terminated before completed flushing", q.name) log.Warn("ChannelQueue: %s Terminated before completed flushing", q.name)
}
return return
} }
log.Debug("ChannelQueue: %s Flushed", q.name) log.Debug("ChannelQueue: %s Flushed", q.name)

View File

@ -95,7 +95,6 @@ func NewPersistableChannelQueue(handle HandlerFunc, cfg, exemplar interface{}) (
Workers: 0, Workers: 0,
}, },
DataDir: config.DataDir, DataDir: config.DataDir,
QueueName: config.Name + "-level",
} }
levelQueue, err := NewLevelQueue(wrappedHandle, levelCfg, exemplar) levelQueue, err := NewLevelQueue(wrappedHandle, levelCfg, exemplar)
@ -173,18 +172,16 @@ func (q *PersistableChannelQueue) Run(atShutdown, atTerminate func(func())) {
atShutdown(q.Shutdown) atShutdown(q.Shutdown)
atTerminate(q.Terminate) atTerminate(q.Terminate)
if lq, ok := q.internal.(*LevelQueue); ok && lq.byteFIFO.Len(lq.terminateCtx) != 0 { if lq, ok := q.internal.(*LevelQueue); ok && lq.byteFIFO.Len(lq.shutdownCtx) != 0 {
// Just run the level queue - we shut it down once it's flushed // Just run the level queue - we shut it down once it's flushed
go q.internal.Run(func(_ func()) {}, func(_ func()) {}) go q.internal.Run(func(_ func()) {}, func(_ func()) {})
go func() { go func() {
for !lq.IsEmpty() { for !q.IsEmpty() {
_ = lq.Flush(0) _ = q.internal.Flush(0)
select { select {
case <-time.After(100 * time.Millisecond): case <-time.After(100 * time.Millisecond):
case <-lq.shutdownCtx.Done(): case <-q.internal.(*LevelQueue).shutdownCtx.Done():
if lq.byteFIFO.Len(lq.terminateCtx) > 0 {
log.Warn("LevelQueue: %s shut down before completely flushed", q.internal.(*LevelQueue).Name()) log.Warn("LevelQueue: %s shut down before completely flushed", q.internal.(*LevelQueue).Name())
}
return return
} }
} }
@ -319,22 +316,10 @@ func (q *PersistableChannelQueue) Shutdown() {
// Redirect all remaining data in the chan to the internal channel // Redirect all remaining data in the chan to the internal channel
log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name) log.Trace("PersistableChannelQueue: %s Redirecting remaining data", q.delayedStarter.name)
close(q.channelQueue.dataChan) close(q.channelQueue.dataChan)
countOK, countLost := 0, 0
for data := range q.channelQueue.dataChan { for data := range q.channelQueue.dataChan {
err := q.internal.Push(data) _ = q.internal.Push(data)
if err != nil {
log.Error("PersistableChannelQueue: %s Unable redirect %v due to: %v", q.delayedStarter.name, data, err)
countLost++
} else {
countOK++
}
atomic.AddInt64(&q.channelQueue.numInQueue, -1) atomic.AddInt64(&q.channelQueue.numInQueue, -1)
} }
if countLost > 0 {
log.Warn("PersistableChannelQueue: %s %d will be restored on restart, %d lost", q.delayedStarter.name, countOK, countLost)
} else if countOK > 0 {
log.Warn("PersistableChannelQueue: %s %d will be restored on restart", q.delayedStarter.name, countOK)
}
log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name) log.Trace("PersistableChannelQueue: %s Done Redirecting remaining data", q.delayedStarter.name)
log.Debug("PersistableChannelQueue: %s Shutdown", q.delayedStarter.name) log.Debug("PersistableChannelQueue: %s Shutdown", q.delayedStarter.name)

View File

@ -39,7 +39,7 @@ func TestPersistableChannelQueue(t *testing.T) {
Workers: 1, Workers: 1,
BoostWorkers: 0, BoostWorkers: 0,
MaxWorkers: 10, MaxWorkers: 10,
Name: "test-queue", Name: "first",
}, &testData{}) }, &testData{})
assert.NoError(t, err) assert.NoError(t, err)
@ -135,7 +135,7 @@ func TestPersistableChannelQueue(t *testing.T) {
Workers: 1, Workers: 1,
BoostWorkers: 0, BoostWorkers: 0,
MaxWorkers: 10, MaxWorkers: 10,
Name: "test-queue", Name: "second",
}, &testData{}) }, &testData{})
assert.NoError(t, err) assert.NoError(t, err)
@ -227,7 +227,7 @@ func TestPersistableChannelQueue_Pause(t *testing.T) {
Workers: 1, Workers: 1,
BoostWorkers: 0, BoostWorkers: 0,
MaxWorkers: 10, MaxWorkers: 10,
Name: "test-queue", Name: "first",
}, &testData{}) }, &testData{})
assert.NoError(t, err) assert.NoError(t, err)
@ -433,7 +433,7 @@ func TestPersistableChannelQueue_Pause(t *testing.T) {
Workers: 1, Workers: 1,
BoostWorkers: 0, BoostWorkers: 0,
MaxWorkers: 10, MaxWorkers: 10,
Name: "test-queue", Name: "second",
}, &testData{}) }, &testData{})
assert.NoError(t, err) assert.NoError(t, err)
pausable, ok = queue.(Pausable) pausable, ok = queue.(Pausable)

View File

@ -177,9 +177,7 @@ func (q *ChannelUniqueQueue) Shutdown() {
go func() { go func() {
log.Trace("ChannelUniqueQueue: %s Flushing", q.name) log.Trace("ChannelUniqueQueue: %s Flushing", q.name)
if err := q.FlushWithContext(q.terminateCtx); err != nil { if err := q.FlushWithContext(q.terminateCtx); err != nil {
if !q.IsEmpty() {
log.Warn("ChannelUniqueQueue: %s Terminated before completed flushing", q.name) log.Warn("ChannelUniqueQueue: %s Terminated before completed flushing", q.name)
}
return return
} }
log.Debug("ChannelUniqueQueue: %s Flushed", q.name) log.Debug("ChannelUniqueQueue: %s Flushed", q.name)

View File

@ -8,13 +8,10 @@ import (
"testing" "testing"
"time" "time"
"code.gitea.io/gitea/modules/log"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestChannelUniqueQueue(t *testing.T) { func TestChannelUniqueQueue(t *testing.T) {
_ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`)
handleChan := make(chan *testData) handleChan := make(chan *testData)
handle := func(data ...Data) []Data { handle := func(data ...Data) []Data {
for _, datum := range data { for _, datum := range data {
@ -55,8 +52,6 @@ func TestChannelUniqueQueue(t *testing.T) {
} }
func TestChannelUniqueQueue_Batch(t *testing.T) { func TestChannelUniqueQueue_Batch(t *testing.T) {
_ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`)
handleChan := make(chan *testData) handleChan := make(chan *testData)
handle := func(data ...Data) []Data { handle := func(data ...Data) []Data {
for _, datum := range data { for _, datum := range data {
@ -103,8 +98,6 @@ func TestChannelUniqueQueue_Batch(t *testing.T) {
} }
func TestChannelUniqueQueue_Pause(t *testing.T) { func TestChannelUniqueQueue_Pause(t *testing.T) {
_ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`)
lock := sync.Mutex{} lock := sync.Mutex{}
var queue Queue var queue Queue
var err error var err error

View File

@ -95,7 +95,6 @@ func NewPersistableChannelUniqueQueue(handle HandlerFunc, cfg, exemplar interfac
Workers: 0, Workers: 0,
}, },
DataDir: config.DataDir, DataDir: config.DataDir,
QueueName: config.Name + "-level",
} }
queue.channelQueue = channelUniqueQueue.(*ChannelUniqueQueue) queue.channelQueue = channelUniqueQueue.(*ChannelUniqueQueue)
@ -210,29 +209,17 @@ func (q *PersistableChannelUniqueQueue) Run(atShutdown, atTerminate func(func())
atTerminate(q.Terminate) atTerminate(q.Terminate)
_ = q.channelQueue.AddWorkers(q.channelQueue.workers, 0) _ = q.channelQueue.AddWorkers(q.channelQueue.workers, 0)
if luq, ok := q.internal.(*LevelUniqueQueue); ok && !luq.IsEmpty() { if luq, ok := q.internal.(*LevelUniqueQueue); ok && luq.ByteFIFOUniqueQueue.byteFIFO.Len(luq.shutdownCtx) != 0 {
// Just run the level queue - we shut it down once it's flushed // Just run the level queue - we shut it down once it's flushed
go luq.Run(func(_ func()) {}, func(_ func()) {}) go q.internal.Run(func(_ func()) {}, func(_ func()) {})
go func() { go func() {
_ = luq.Flush(0) _ = q.internal.Flush(0)
for !luq.IsEmpty() { log.Debug("LevelUniqueQueue: %s flushed so shutting down", q.internal.(*LevelUniqueQueue).Name())
_ = luq.Flush(0) q.internal.(*LevelUniqueQueue).Shutdown()
select { GetManager().Remove(q.internal.(*LevelUniqueQueue).qid)
case <-time.After(100 * time.Millisecond):
case <-luq.shutdownCtx.Done():
if luq.byteFIFO.Len(luq.terminateCtx) > 0 {
log.Warn("LevelUniqueQueue: %s shut down before completely flushed", luq.Name())
}
return
}
}
log.Debug("LevelUniqueQueue: %s flushed so shutting down", luq.Name())
luq.Shutdown()
GetManager().Remove(luq.qid)
}() }()
} else { } else {
log.Debug("PersistableChannelUniqueQueue: %s Skipping running the empty level queue", q.delayedStarter.name) log.Debug("PersistableChannelUniqueQueue: %s Skipping running the empty level queue", q.delayedStarter.name)
_ = q.internal.Flush(0)
q.internal.(*LevelUniqueQueue).Shutdown() q.internal.(*LevelUniqueQueue).Shutdown()
GetManager().Remove(q.internal.(*LevelUniqueQueue).qid) GetManager().Remove(q.internal.(*LevelUniqueQueue).qid)
} }
@ -298,20 +285,8 @@ func (q *PersistableChannelUniqueQueue) Shutdown() {
// Redirect all remaining data in the chan to the internal channel // Redirect all remaining data in the chan to the internal channel
close(q.channelQueue.dataChan) close(q.channelQueue.dataChan)
log.Trace("PersistableChannelUniqueQueue: %s Redirecting remaining data", q.delayedStarter.name) log.Trace("PersistableChannelUniqueQueue: %s Redirecting remaining data", q.delayedStarter.name)
countOK, countLost := 0, 0
for data := range q.channelQueue.dataChan { for data := range q.channelQueue.dataChan {
err := q.internal.(*LevelUniqueQueue).Push(data) _ = q.internal.Push(data)
if err != nil {
log.Error("PersistableChannelUniqueQueue: %s Unable redirect %v due to: %v", q.delayedStarter.name, data, err)
countLost++
} else {
countOK++
}
}
if countLost > 0 {
log.Warn("PersistableChannelUniqueQueue: %s %d will be restored on restart, %d lost", q.delayedStarter.name, countOK, countLost)
} else if countOK > 0 {
log.Warn("PersistableChannelUniqueQueue: %s %d will be restored on restart", q.delayedStarter.name, countOK)
} }
log.Trace("PersistableChannelUniqueQueue: %s Done Redirecting remaining data", q.delayedStarter.name) log.Trace("PersistableChannelUniqueQueue: %s Done Redirecting remaining data", q.delayedStarter.name)

View File

@ -1,259 +0,0 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package queue
import (
"fmt"
"strconv"
"sync"
"testing"
"time"
"code.gitea.io/gitea/modules/log"
"github.com/stretchr/testify/assert"
)
func TestPersistableChannelUniqueQueue(t *testing.T) {
tmpDir := t.TempDir()
fmt.Printf("TempDir %s\n", tmpDir)
_ = log.NewLogger(1000, "console", "console", `{"level":"warn","stacktracelevel":"NONE","stderr":true}`)
// Common function to create the Queue
newQueue := func(name string, handle func(data ...Data) []Data) Queue {
q, err := NewPersistableChannelUniqueQueue(handle,
PersistableChannelUniqueQueueConfiguration{
Name: name,
DataDir: tmpDir,
QueueLength: 200,
MaxWorkers: 1,
BlockTimeout: 1 * time.Second,
BoostTimeout: 5 * time.Minute,
BoostWorkers: 1,
Workers: 0,
}, "task-0")
assert.NoError(t, err)
return q
}
// runs the provided queue and provides some timer function
type channels struct {
readyForShutdown chan struct{} // closed when shutdown functions have been assigned
readyForTerminate chan struct{} // closed when terminate functions have been assigned
signalShutdown chan struct{} // Should close to signal shutdown
doneShutdown chan struct{} // closed when shutdown function is done
queueTerminate []func() // list of atTerminate functions to call atTerminate - need to be accessed with lock
}
runQueue := func(q Queue, lock *sync.Mutex) *channels {
chans := &channels{
readyForShutdown: make(chan struct{}),
readyForTerminate: make(chan struct{}),
signalShutdown: make(chan struct{}),
doneShutdown: make(chan struct{}),
}
go q.Run(func(atShutdown func()) {
go func() {
lock.Lock()
select {
case <-chans.readyForShutdown:
default:
close(chans.readyForShutdown)
}
lock.Unlock()
<-chans.signalShutdown
atShutdown()
close(chans.doneShutdown)
}()
}, func(atTerminate func()) {
lock.Lock()
defer lock.Unlock()
select {
case <-chans.readyForTerminate:
default:
close(chans.readyForTerminate)
}
chans.queueTerminate = append(chans.queueTerminate, atTerminate)
})
return chans
}
// call to shutdown and terminate the queue associated with the channels
doTerminate := func(chans *channels, lock *sync.Mutex) {
<-chans.readyForTerminate
lock.Lock()
callbacks := []func(){}
callbacks = append(callbacks, chans.queueTerminate...)
lock.Unlock()
for _, callback := range callbacks {
callback()
}
}
mapLock := sync.Mutex{}
executedInitial := map[string][]string{}
hasInitial := map[string][]string{}
fillQueue := func(name string, done chan struct{}) {
t.Run("Initial Filling: "+name, func(t *testing.T) {
lock := sync.Mutex{}
startAt100Queued := make(chan struct{})
stopAt20Shutdown := make(chan struct{}) // stop and shutdown at the 20th item
handle := func(data ...Data) []Data {
<-startAt100Queued
for _, datum := range data {
s := datum.(string)
mapLock.Lock()
executedInitial[name] = append(executedInitial[name], s)
mapLock.Unlock()
if s == "task-20" {
close(stopAt20Shutdown)
}
}
return nil
}
q := newQueue(name, handle)
// add 100 tasks to the queue
for i := 0; i < 100; i++ {
_ = q.Push("task-" + strconv.Itoa(i))
}
close(startAt100Queued)
chans := runQueue(q, &lock)
<-chans.readyForShutdown
<-stopAt20Shutdown
close(chans.signalShutdown)
<-chans.doneShutdown
_ = q.Push("final")
// check which tasks are still in the queue
for i := 0; i < 100; i++ {
if has, _ := q.(UniqueQueue).Has("task-" + strconv.Itoa(i)); has {
mapLock.Lock()
hasInitial[name] = append(hasInitial[name], "task-"+strconv.Itoa(i))
mapLock.Unlock()
}
}
if has, _ := q.(UniqueQueue).Has("final"); has {
mapLock.Lock()
hasInitial[name] = append(hasInitial[name], "final")
mapLock.Unlock()
} else {
assert.Fail(t, "UnqueQueue %s should have \"final\"", name)
}
doTerminate(chans, &lock)
mapLock.Lock()
assert.Equal(t, 101, len(executedInitial[name])+len(hasInitial[name]))
mapLock.Unlock()
})
close(done)
}
doneA := make(chan struct{})
doneB := make(chan struct{})
go fillQueue("QueueA", doneA)
go fillQueue("QueueB", doneB)
<-doneA
<-doneB
executedEmpty := map[string][]string{}
hasEmpty := map[string][]string{}
emptyQueue := func(name string, done chan struct{}) {
t.Run("Empty Queue: "+name, func(t *testing.T) {
lock := sync.Mutex{}
stop := make(chan struct{})
// collect the tasks that have been executed
handle := func(data ...Data) []Data {
lock.Lock()
for _, datum := range data {
mapLock.Lock()
executedEmpty[name] = append(executedEmpty[name], datum.(string))
mapLock.Unlock()
if datum.(string) == "final" {
close(stop)
}
}
lock.Unlock()
return nil
}
q := newQueue(name, handle)
chans := runQueue(q, &lock)
<-chans.readyForShutdown
<-stop
close(chans.signalShutdown)
<-chans.doneShutdown
// check which tasks are still in the queue
for i := 0; i < 100; i++ {
if has, _ := q.(UniqueQueue).Has("task-" + strconv.Itoa(i)); has {
mapLock.Lock()
hasEmpty[name] = append(hasEmpty[name], "task-"+strconv.Itoa(i))
mapLock.Unlock()
}
}
doTerminate(chans, &lock)
mapLock.Lock()
assert.Equal(t, 101, len(executedInitial[name])+len(executedEmpty[name]))
assert.Equal(t, 0, len(hasEmpty[name]))
mapLock.Unlock()
})
close(done)
}
doneA = make(chan struct{})
doneB = make(chan struct{})
go emptyQueue("QueueA", doneA)
go emptyQueue("QueueB", doneB)
<-doneA
<-doneB
mapLock.Lock()
t.Logf("TestPersistableChannelUniqueQueue executedInitiallyA=%v, executedInitiallyB=%v, executedToEmptyA=%v, executedToEmptyB=%v",
len(executedInitial["QueueA"]), len(executedInitial["QueueB"]), len(executedEmpty["QueueA"]), len(executedEmpty["QueueB"]))
// reset and rerun
executedInitial = map[string][]string{}
hasInitial = map[string][]string{}
executedEmpty = map[string][]string{}
hasEmpty = map[string][]string{}
mapLock.Unlock()
doneA = make(chan struct{})
doneB = make(chan struct{})
go fillQueue("QueueA", doneA)
go fillQueue("QueueB", doneB)
<-doneA
<-doneB
doneA = make(chan struct{})
doneB = make(chan struct{})
go emptyQueue("QueueA", doneA)
go emptyQueue("QueueB", doneB)
<-doneA
<-doneB
mapLock.Lock()
t.Logf("TestPersistableChannelUniqueQueue executedInitiallyA=%v, executedInitiallyB=%v, executedToEmptyA=%v, executedToEmptyB=%v",
len(executedInitial["QueueA"]), len(executedInitial["QueueB"]), len(executedEmpty["QueueA"]), len(executedEmpty["QueueB"]))
mapLock.Unlock()
}

View File

@ -248,7 +248,6 @@ no_reply_address_helper=Nome de domínio para usuários com um endereço de e-ma
password_algorithm=Algoritmo Hash de Senha password_algorithm=Algoritmo Hash de Senha
password_algorithm_helper=Escolha o algoritmo de hash para as senhas. Diferentes algoritmos têm requerimentos e forças diversos. O `Argon2` possui boa qualidade, porém usa muita memória e pode ser inapropriado para sistemas com menos recursos. password_algorithm_helper=Escolha o algoritmo de hash para as senhas. Diferentes algoritmos têm requerimentos e forças diversos. O `Argon2` possui boa qualidade, porém usa muita memória e pode ser inapropriado para sistemas com menos recursos.
enable_update_checker=Habilitar Verificador de Atualizações enable_update_checker=Habilitar Verificador de Atualizações
enable_update_checker_helper=Procura por novas versões periodicamente conectando-se ao gitea.io.
[home] [home]
uname_holder=Usuário ou e-mail uname_holder=Usuário ou e-mail
@ -284,9 +283,7 @@ organizations=Organizações
search=Pesquisar search=Pesquisar
code=Código code=Código
search.fuzzy=Similar search.fuzzy=Similar
search.fuzzy.tooltip=Incluir resultados que sejam próximos ao termo de busca
search.match=Correspondência search.match=Correspondência
search.match.tooltip=Incluir somente resultados que correspondam exatamente ao termo de busca
code_search_unavailable=A pesquisa por código não está disponível no momento. Entre em contato com o administrador do site. code_search_unavailable=A pesquisa por código não está disponível no momento. Entre em contato com o administrador do site.
repo_no_results=Nenhum repositório correspondente foi encontrado. repo_no_results=Nenhum repositório correspondente foi encontrado.
user_no_results=Nenhum usuário correspondente foi encontrado. user_no_results=Nenhum usuário correspondente foi encontrado.
@ -368,7 +365,6 @@ password_pwned_err=Não foi possível concluir a requisição ao HaveIBeenPwned
[mail] [mail]
view_it_on=Veja em %s view_it_on=Veja em %s
reply=ou responda diretamente a este email
link_not_working_do_paste=Não está funcionando? Tente copiá-lo e colá-lo no seu navegador. link_not_working_do_paste=Não está funcionando? Tente copiá-lo e colá-lo no seu navegador.
hi_user_x=Olá <b>%s</b>, hi_user_x=Olá <b>%s</b>,
@ -427,10 +423,6 @@ repo.transfer.body=Para o aceitar ou rejeitar visite %s, ou simplesmente o ignor
repo.collaborator.added.subject=%s adicionou você a %s repo.collaborator.added.subject=%s adicionou você a %s
repo.collaborator.added.text=Você foi adicionado como um colaborador do repositório: repo.collaborator.added.text=Você foi adicionado como um colaborador do repositório:
team_invite.subject=%[1]s convidou você para participar da organização %[2]s
team_invite.text_1=%[1]s convidou você para participar da equipe %[2]s na organização %[3]s.
team_invite.text_2=Por favor, clique no seguinte link para se juntar à equipe:
team_invite.text_3=Nota: este convite foi destinado a %[1]s. Se você não estava esperando este convite, você pode ignorar este e-mail.
[modal] [modal]
yes=Sim yes=Sim
@ -511,7 +503,6 @@ cannot_add_org_to_team=Uma organização não pode ser adicionada como membro de
invalid_ssh_key=Não é possível verificar sua chave SSH: %s invalid_ssh_key=Não é possível verificar sua chave SSH: %s
invalid_gpg_key=Não é possível verificar sua chave GPG: %s invalid_gpg_key=Não é possível verificar sua chave GPG: %s
invalid_ssh_principal=Nome principal inválido: %s invalid_ssh_principal=Nome principal inválido: %s
must_use_public_key=A chave que você forneceu é uma chave privada. Por favor, não envie sua chave privada em nenhum lugar. Use sua chave pública em vez disso.
unable_verify_ssh_key=Não é possível verificar sua chave SSH unable_verify_ssh_key=Não é possível verificar sua chave SSH
auth_failed=Autenticação falhou: %v auth_failed=Autenticação falhou: %v
@ -1209,7 +1200,6 @@ projects.type.uncategorized=Sem categoria
projects.column.edit_title=Nome projects.column.edit_title=Nome
projects.column.new_title=Nome projects.column.new_title=Nome
projects.column.new=Nova Coluna projects.column.new=Nova Coluna
projects.column.delete=Excluir coluna
projects.column.color=Colorido projects.column.color=Colorido
projects.open=Abrir projects.open=Abrir
projects.close=Fechar projects.close=Fechar
@ -1783,9 +1773,7 @@ activity.git_stats_deletion_n=%d exclusões
search=Pesquisar search=Pesquisar
search.search_repo=Pesquisar no repositório... search.search_repo=Pesquisar no repositório...
search.fuzzy=Aproximada search.fuzzy=Aproximada
search.fuzzy.tooltip=Incluir resultados que sejam próximos ao termo de busca
search.match=Corresponde search.match=Corresponde
search.match.tooltip=Incluir somente resultados que correspondam exatamente ao termo de busca
search.results=Resultados da pesquisa para "%s" em <a href="%s">%s</a> search.results=Resultados da pesquisa para "%s" em <a href="%s">%s</a>
search.code_no_results=Nenhum código-fonte correspondente ao seu termo de pesquisa foi encontrado. search.code_no_results=Nenhum código-fonte correspondente ao seu termo de pesquisa foi encontrado.
search.code_search_unavailable=A pesquisa por código não está disponível no momento. Entre em contato com o administrador do site. search.code_search_unavailable=A pesquisa por código não está disponível no momento. Entre em contato com o administrador do site.

View File

@ -57,7 +57,6 @@ new_mirror=Nova réplica
new_fork=Nova derivação do repositório new_fork=Nova derivação do repositório
new_org=Nova organização new_org=Nova organização
new_project=Novo planeamento new_project=Novo planeamento
new_project_column=Nova coluna
manage_org=Gerir organizações manage_org=Gerir organizações
admin_panel=Administração do sítio admin_panel=Administração do sítio
account_settings=Configurações da conta account_settings=Configurações da conta
@ -91,7 +90,6 @@ disabled=Desabilitado
copy=Copiar copy=Copiar
copy_url=Copiar URL copy_url=Copiar URL
copy_content=Copiar conteúdo
copy_branch=Copiar nome do ramo copy_branch=Copiar nome do ramo
copy_success=Copiado! copy_success=Copiado!
copy_error=Falha ao copiar copy_error=Falha ao copiar
@ -111,10 +109,6 @@ never=Nunca
rss_feed=Fonte RSS rss_feed=Fonte RSS
[aria] [aria]
navbar=Barra de navegação
footer=Rodapé
footer.software=Sobre o Software
footer.links=Ligações
[filter] [filter]
string.asc=A - Z string.asc=A - Z
@ -370,7 +364,6 @@ password_pwned_err=Não foi possível completar o pedido ao HaveIBeenPwned
[mail] [mail]
view_it_on=Ver em %s view_it_on=Ver em %s
reply=ou responda a este email imediatamente
link_not_working_do_paste=Não está a funcionar? Tente copiar e colar no seu navegador. link_not_working_do_paste=Não está a funcionar? Tente copiar e colar no seu navegador.
hi_user_x=Olá <b>%s</b>, hi_user_x=Olá <b>%s</b>,
@ -474,8 +467,6 @@ url_error=`'%s' não é um URL válido.`
include_error=` tem que conter o texto '%s'.` include_error=` tem que conter o texto '%s'.`
glob_pattern_error=` o padrão glob é inválido: %s.` glob_pattern_error=` o padrão glob é inválido: %s.`
regex_pattern_error=` o padrão regex é inválido: %s.` regex_pattern_error=` o padrão regex é inválido: %s.`
username_error=` só pode conter caracteres alfanuméricos ('0-9','a-z','A-Z'), hífen ('-'), sublinhado ('_') e ponto ('.') Não pode começar nem terminar com caracteres não alfanuméricos, e caracteres não alfanuméricos consecutivos também são proibidos.`
invalid_group_team_map_error=` o mapeamento é inválido: %s`
unknown_error=Erro desconhecido: unknown_error=Erro desconhecido:
captcha_incorrect=O código CAPTCHA está errado. captcha_incorrect=O código CAPTCHA está errado.
password_not_match=As senhas não coincidem. password_not_match=As senhas não coincidem.
@ -512,12 +503,10 @@ team_not_exist=A equipa não existe.
last_org_owner=Não pode remover o último utilizador da equipa 'proprietários'. Tem que haver pelo menos um proprietário numa organização. last_org_owner=Não pode remover o último utilizador da equipa 'proprietários'. Tem que haver pelo menos um proprietário numa organização.
cannot_add_org_to_team=Uma organização não pode ser adicionada como membro de uma equipa. cannot_add_org_to_team=Uma organização não pode ser adicionada como membro de uma equipa.
duplicate_invite_to_team=O(A) utilizador(a) já tinha sido convidado(a) para ser membro da equipa. duplicate_invite_to_team=O(A) utilizador(a) já tinha sido convidado(a) para ser membro da equipa.
organization_leave_success=Você deixou a organização %s com sucesso.
invalid_ssh_key=Não é possível validar a sua chave SSH: %s invalid_ssh_key=Não é possível validar a sua chave SSH: %s
invalid_gpg_key=Não é possível validar a sua chave GPG: %s invalid_gpg_key=Não é possível validar a sua chave GPG: %s
invalid_ssh_principal=Protagonista inválido: %s invalid_ssh_principal=Protagonista inválido: %s
must_use_public_key=A chave que você forneceu é privada. Não carregue a sua chave em lugar nenhum, em vez disso use a sua chave pública.
unable_verify_ssh_key=Não é possível validar a chave SSH unable_verify_ssh_key=Não é possível validar a chave SSH
auth_failed=Falhou a autenticação: %v auth_failed=Falhou a autenticação: %v
@ -754,8 +743,6 @@ access_token_deletion_cancel_action=Cancelar
access_token_deletion_confirm_action=Eliminar access_token_deletion_confirm_action=Eliminar
access_token_deletion_desc=Eliminar um código revoga o acesso à sua conta nas aplicações que o usem. Esta operação não poderá ser revertida. Quer continuar? access_token_deletion_desc=Eliminar um código revoga o acesso à sua conta nas aplicações que o usem. Esta operação não poderá ser revertida. Quer continuar?
delete_token_success=O código foi eliminado. Aplicações que o usavam deixaram de ter acesso à sua conta. delete_token_success=O código foi eliminado. Aplicações que o usavam deixaram de ter acesso à sua conta.
select_scopes=Escolha os âmbitos
scopes_list=Âmbitos:
manage_oauth2_applications=Gerir aplicações OAuth2 manage_oauth2_applications=Gerir aplicações OAuth2
edit_oauth2_application=Editar aplicação OAuth2 edit_oauth2_application=Editar aplicação OAuth2
@ -1028,12 +1015,10 @@ unstar=Tirar dos favoritos
star=Juntar aos favoritos star=Juntar aos favoritos
fork=Derivar fork=Derivar
download_archive=Descarregar repositório download_archive=Descarregar repositório
more_operations=Mais operações
no_desc=Sem descrição no_desc=Sem descrição
quick_guide=Guia rápido quick_guide=Guia rápido
clone_this_repo=Clonar este repositório clone_this_repo=Clonar este repositório
cite_this_repo=Citar este repositório
create_new_repo_command=Criando um novo repositório na linha de comandos create_new_repo_command=Criando um novo repositório na linha de comandos
push_exist_repo=Enviando, pela linha de comandos, um repositório existente push_exist_repo=Enviando, pela linha de comandos, um repositório existente
empty_message=Este repositório não contém qualquer conteúdo. empty_message=Este repositório não contém qualquer conteúdo.
@ -1132,7 +1117,6 @@ editor.commit_directly_to_this_branch=Cometer imediatamente no ramo <strong clas
editor.create_new_branch=Crie um <strong>novo ramo</strong> para este cometimento e inicie um pedido de integração. editor.create_new_branch=Crie um <strong>novo ramo</strong> para este cometimento e inicie um pedido de integração.
editor.create_new_branch_np=Criar um <strong>novo ramo</strong> para este cometimento. editor.create_new_branch_np=Criar um <strong>novo ramo</strong> para este cometimento.
editor.propose_file_change=Propor modificação do ficheiro editor.propose_file_change=Propor modificação do ficheiro
editor.new_branch_name=Dê um nome ao novo ramo para este cometimento
editor.new_branch_name_desc=Nome do novo ramo… editor.new_branch_name_desc=Nome do novo ramo…
editor.cancel=Cancelar editor.cancel=Cancelar
editor.filename_cannot_be_empty=O nome do ficheiro não pode estar em branco. editor.filename_cannot_be_empty=O nome do ficheiro não pode estar em branco.
@ -1184,7 +1168,6 @@ commits.signed_by_untrusted_user_unmatched=Assinado por um utilizador não fiáv
commits.gpg_key_id=ID da chave GPG commits.gpg_key_id=ID da chave GPG
commits.ssh_key_fingerprint=Identificação digital da chave SSH commits.ssh_key_fingerprint=Identificação digital da chave SSH
commit.operations=Operações
commit.revert=Reverter commit.revert=Reverter
commit.revert-header=Reverter: %s commit.revert-header=Reverter: %s
commit.revert-content=Escolha o ramo para onde vai reverter: commit.revert-content=Escolha o ramo para onde vai reverter:
@ -1217,22 +1200,11 @@ projects.type.bug_triage=Triagem de erros
projects.template.desc=Modelo de planeamento projects.template.desc=Modelo de planeamento
projects.template.desc_helper=Escolha um modelo de planeamento para começar projects.template.desc_helper=Escolha um modelo de planeamento para começar
projects.type.uncategorized=Sem categoria projects.type.uncategorized=Sem categoria
projects.column.edit=Editar coluna
projects.column.edit_title=Nome projects.column.edit_title=Nome
projects.column.new_title=Nome projects.column.new_title=Nome
projects.column.new_submit=Criar coluna
projects.column.new=Nova coluna
projects.column.set_default=Definir como padrão
projects.column.set_default_desc=Defina esta coluna como padrão para questões e pedidos de integração não categorizados
projects.column.delete=Eliminar coluna
projects.column.deletion_desc=Eliminar uma coluna de um planeamento faz com que todas as questões que nela constam sejam movidas para a coluna 'Sem categoria'. Continuar?
projects.column.color=Colorido projects.column.color=Colorido
projects.open=Abrir projects.open=Abrir
projects.close=Fechar projects.close=Fechar
projects.column.assigned_to=Atribuída a
projects.card_type.desc=Previsão dos cartões
projects.card_type.images_and_text=Imagens e texto
projects.card_type.text_only=Apenas texto
issues.desc=Organize relatórios de erros, tarefas e etapas. issues.desc=Organize relatórios de erros, tarefas e etapas.
issues.filter_assignees=Filtrar encarregado issues.filter_assignees=Filtrar encarregado
@ -1309,7 +1281,6 @@ issues.filter_label_no_select=Todos os rótulos
issues.filter_milestone=Etapa issues.filter_milestone=Etapa
issues.filter_milestone_no_select=Todas as etapas issues.filter_milestone_no_select=Todas as etapas
issues.filter_project=Planeamento issues.filter_project=Planeamento
issues.filter_project_all=Todos os planeamentos
issues.filter_project_none=Nenhum planeamento issues.filter_project_none=Nenhum planeamento
issues.filter_assignee=Encarregado issues.filter_assignee=Encarregado
issues.filter_assginee_no_select=Todos os encarregados issues.filter_assginee_no_select=Todos os encarregados
@ -1321,7 +1292,6 @@ issues.filter_type.assigned_to_you=Atribuídas a si
issues.filter_type.created_by_you=Criadas por si issues.filter_type.created_by_you=Criadas por si
issues.filter_type.mentioning_you=Mencionando a si issues.filter_type.mentioning_you=Mencionando a si
issues.filter_type.review_requested=Revisão solicitada issues.filter_type.review_requested=Revisão solicitada
issues.filter_type.reviewed_by_you=Revistos por si
issues.filter_sort=Ordem issues.filter_sort=Ordem
issues.filter_sort.latest=Mais recentes issues.filter_sort.latest=Mais recentes
issues.filter_sort.oldest=Mais antigas issues.filter_sort.oldest=Mais antigas
@ -1343,8 +1313,6 @@ issues.action_milestone=Etapa
issues.action_milestone_no_select=Sem etapa issues.action_milestone_no_select=Sem etapa
issues.action_assignee=Encarregado issues.action_assignee=Encarregado
issues.action_assignee_no_select=Sem encarregado issues.action_assignee_no_select=Sem encarregado
issues.action_check=Marcar/desmarcar
issues.action_check_all=Marcar/desmarcar todos os itens
issues.opened_by=aberta %[1]s por <a href="%[2]s">%[3]s</a> issues.opened_by=aberta %[1]s por <a href="%[2]s">%[3]s</a>
pulls.merged_by=por <a href="%[2]s">%[3]s</a> foi executado %[1]s pulls.merged_by=por <a href="%[2]s">%[3]s</a> foi executado %[1]s
pulls.merged_by_fake=por %[2]s foi executado %[1]s pulls.merged_by_fake=por %[2]s foi executado %[1]s
@ -1398,9 +1366,6 @@ issues.save=Guardar
issues.label_title=Nome do rótulo issues.label_title=Nome do rótulo
issues.label_description=Descrição do rótulo issues.label_description=Descrição do rótulo
issues.label_color=Cor do rótulo issues.label_color=Cor do rótulo
issues.label_exclusive=Exclusivo
issues.label_exclusive_desc=Nomeie o rótulo <code>âmbito/item</code> para torná-lo mutuamente exclusivo com outros rótulos do <code>âmbito/</code>.
issues.label_exclusive_warning=Quaisquer rótulos com âmbito que estejam em conflito irão ser removidos ao editar os rótulos de uma questão ou de um pedido de integração.
issues.label_count=%d rótulos issues.label_count=%d rótulos
issues.label_open_issues=%d questões abertas issues.label_open_issues=%d questões abertas
issues.label_edit=Editar issues.label_edit=Editar
@ -1654,8 +1619,6 @@ pulls.reopened_at=`reabriu este pedido de integração <a id="%[1]s" href="#%[1]
pulls.merge_instruction_hint=`Também pode ver as <a class="show-instruction">instruções para a linha de comandos</a>.` pulls.merge_instruction_hint=`Também pode ver as <a class="show-instruction">instruções para a linha de comandos</a>.`
pulls.merge_instruction_step1_desc=No seu repositório, crie um novo ramo e teste as modificações. pulls.merge_instruction_step1_desc=No seu repositório, crie um novo ramo e teste as modificações.
pulls.merge_instruction_step2_desc=Integre as modificações e envie para o Gitea. pulls.merge_instruction_step2_desc=Integre as modificações e envie para o Gitea.
pulls.clear_merge_message=Apagar mensagem de integração
pulls.clear_merge_message_hint=Apagar a mensagem de integração apenas remove o conteúdo da mensagem de cometimento e mantém os rodapés do git, tais como "Co-Autorado-Por …".
pulls.auto_merge_button_when_succeed=(quando as verificações forem bem-sucedidas) pulls.auto_merge_button_when_succeed=(quando as verificações forem bem-sucedidas)
pulls.auto_merge_when_succeed=Integrar automaticamente quando todas as verificações forem bem-sucedidas pulls.auto_merge_when_succeed=Integrar automaticamente quando todas as verificações forem bem-sucedidas
@ -1847,7 +1810,6 @@ settings.mirror_sync_in_progress=A sincronização da réplica está em andament
settings.site=Sítio web settings.site=Sítio web
settings.update_settings=Modificar configurações settings.update_settings=Modificar configurações
settings.branches.update_default_branch=Definir o ramo principal settings.branches.update_default_branch=Definir o ramo principal
settings.branches.add_new_rule=Adicionar nova regra
settings.advanced_settings=Configurações avançadas settings.advanced_settings=Configurações avançadas
settings.wiki_desc=Habilitar wiki do repositório settings.wiki_desc=Habilitar wiki do repositório
settings.use_internal_wiki=Usar o wiki nativo settings.use_internal_wiki=Usar o wiki nativo
@ -1877,11 +1839,8 @@ settings.pulls.ignore_whitespace=Ignorar espaços em branco nos conflitos
settings.pulls.enable_autodetect_manual_merge=Habilitar a identificação automática de integrações manuais (obs.: nalguns casos especiais a avaliação pode ser errada) settings.pulls.enable_autodetect_manual_merge=Habilitar a identificação automática de integrações manuais (obs.: nalguns casos especiais a avaliação pode ser errada)
settings.pulls.allow_rebase_update=Habilitar a modificação do ramo do pedido de integração através da mudança de base settings.pulls.allow_rebase_update=Habilitar a modificação do ramo do pedido de integração através da mudança de base
settings.pulls.default_delete_branch_after_merge=Eliminar o ramo do pedido de integração depois de finalizada a integração, como predefinição settings.pulls.default_delete_branch_after_merge=Eliminar o ramo do pedido de integração depois de finalizada a integração, como predefinição
settings.pulls.default_allow_edits_from_maintainers=Permitir, por padrão, que os responsáveis editem
settings.releases_desc=Habilitar lançamentos no repositório
settings.packages_desc=Habilitar o registo de pacotes do repositório settings.packages_desc=Habilitar o registo de pacotes do repositório
settings.projects_desc=Habilitar planeamentos no repositório settings.projects_desc=Habilitar planeamentos no repositório
settings.actions_desc=Habilitar operações no repositório
settings.admin_settings=Configurações do administrador settings.admin_settings=Configurações do administrador
settings.admin_enable_health_check=Habilitar verificações de integridade (git fsck) no repositório settings.admin_enable_health_check=Habilitar verificações de integridade (git fsck) no repositório
settings.admin_code_indexer=Indexador de código settings.admin_code_indexer=Indexador de código
@ -3011,7 +2970,6 @@ monitor.queue.pool.cancel_desc=Deixar uma fila sem quaisquer grupos de trabalhad
notices.system_notice_list=Notificações do sistema notices.system_notice_list=Notificações do sistema
notices.view_detail_header=Ver os detalhes da notificação notices.view_detail_header=Ver os detalhes da notificação
notices.operations=Operações
notices.select_all=Marcar todas notices.select_all=Marcar todas
notices.deselect_all=Desmarcar todas notices.deselect_all=Desmarcar todas
notices.inverse_selection=Inverter as marcações notices.inverse_selection=Inverter as marcações
@ -3212,15 +3170,6 @@ settings.delete.notice=Está prestes a eliminar %s (%s). Esta operação é irre
settings.delete.success=O pacote foi eliminado. settings.delete.success=O pacote foi eliminado.
settings.delete.error=Falhou a eliminação do pacote. settings.delete.error=Falhou a eliminação do pacote.
owner.settings.cleanuprules.enabled=Habilitado owner.settings.cleanuprules.enabled=Habilitado
owner.settings.cleanuprules.keep.count=Manter a mais recente
owner.settings.cleanuprules.keep.count.1=1 versão por pacote
owner.settings.cleanuprules.keep.count.n=%d versões por pacote
owner.settings.cleanuprules.keep.pattern=Manter as versões correspondentes
owner.settings.cleanuprules.keep.pattern.container=A <code>última</code> versão será sempre mantida para pacotes de contentor.
owner.settings.cleanuprules.remove.title=Versões que correspondam a estas regras serão removidos, a não ser que a regra acima diga para os manter.
owner.settings.cleanuprules.remove.days=Remover versões mais antigas do que
owner.settings.cleanuprules.remove.pattern=Remover as versões correspondentes
owner.settings.cleanuprules.success.update=A regra de limpeza foi modificada.
[secrets] [secrets]
value=Valor value=Valor
@ -3238,16 +3187,8 @@ runners.labels=Rótulos
runners.task_list.run=Executar runners.task_list.run=Executar
runners.task_list.repository=Repositório runners.task_list.repository=Repositório
runners.task_list.commit=Cometimento runners.task_list.commit=Cometimento
runners.delete_runner=Eliminar o executor
runners.status.idle=Parada
runners.status.active=Em funcionamento runners.status.active=Em funcionamento
runners.status.offline=Desconectada
runs.all_workflows=Todos os fluxos de trabalho
runs.open_tab=%d abertas
runs.closed_tab=%d fechadas
runs.commit=Cometimento runs.commit=Cometimento
runs.pushed_by=Enviada por
need_approval_desc=É necessária aprovação para executar fluxos de trabalho para a derivação do pedido de integração.

View File

@ -12,7 +12,6 @@ import (
"code.gitea.io/gitea/modules/actions" "code.gitea.io/gitea/modules/actions"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/util"
actions_service "code.gitea.io/gitea/services/actions" actions_service "code.gitea.io/gitea/services/actions"
runnerv1 "code.gitea.io/actions-proto-go/runner/v1" runnerv1 "code.gitea.io/actions-proto-go/runner/v1"
@ -56,10 +55,9 @@ func (s *Service) Register(
} }
// create new runner // create new runner
name, _ := util.SplitStringAtByteN(req.Msg.Name, 255)
runner := &actions_model.ActionRunner{ runner := &actions_model.ActionRunner{
UUID: gouuid.New().String(), UUID: gouuid.New().String(),
Name: name, Name: req.Msg.Name,
OwnerID: runnerToken.OwnerID, OwnerID: runnerToken.OwnerID,
RepoID: runnerToken.RepoID, RepoID: runnerToken.RepoID,
AgentLabels: req.Msg.AgentLabels, AgentLabels: req.Msg.AgentLabels,

View File

@ -45,7 +45,7 @@ func ListUnadoptedRepositories(ctx *context.APIContext) {
if listOptions.Page == 0 { if listOptions.Page == 0 {
listOptions.Page = 1 listOptions.Page = 1
} }
repoNames, count, err := repo_service.ListUnadoptedRepositories(ctx, ctx.FormString("query"), &listOptions) repoNames, count, err := repo_service.ListUnadoptedRepositories(ctx.FormString("query"), &listOptions)
if err != nil { if err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
@ -109,7 +109,7 @@ func AdoptRepository(ctx *context.APIContext) {
ctx.NotFound() ctx.NotFound()
return return
} }
if _, err := repo_service.AdoptRepository(ctx, ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{
Name: repoName, Name: repoName,
IsPrivate: true, IsPrivate: true,
}); err != nil { }); err != nil {
@ -172,7 +172,7 @@ func DeleteUnadoptedRepository(ctx *context.APIContext) {
return return
} }
if err := repo_service.DeleteUnadoptedRepository(ctx, ctx.Doer, ctxUser, repoName); err != nil { if err := repo_service.DeleteUnadoptedRepository(ctx.Doer, ctxUser, repoName); err != nil {
ctx.InternalServerError(err) ctx.InternalServerError(err)
return return
} }

View File

@ -118,7 +118,7 @@ func DeleteBranch(ctx *context.APIContext) {
branchName := ctx.Params("*") branchName := ctx.Params("*")
if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil { if err := repo_service.DeleteBranch(ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
switch { switch {
case git.IsErrBranchNotExist(err): case git.IsErrBranchNotExist(err):
ctx.NotFound(err) ctx.NotFound(err)

View File

@ -904,7 +904,7 @@ func MergePullRequest(ctx *context.APIContext) {
} }
defer headRepo.Close() defer headRepo.Close()
} }
if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch); err != nil { if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, headRepo, pr.HeadBranch); err != nil {
switch { switch {
case git.IsErrBranchNotExist(err): case git.IsErrBranchNotExist(err):
ctx.NotFound(err) ctx.NotFound(err)

View File

@ -230,7 +230,7 @@ func CreateUserRepo(ctx *context.APIContext, owner *user_model.User, opt api.Cre
if opt.AutoInit && opt.Readme == "" { if opt.AutoInit && opt.Readme == "" {
opt.Readme = "Default" opt.Readme = "Default"
} }
repo, err := repo_service.CreateRepository(ctx, ctx.Doer, owner, repo_module.CreateRepoOptions{ repo, err := repo_service.CreateRepository(ctx.Doer, owner, repo_module.CreateRepoOptions{
Name: opt.Name, Name: opt.Name,
Description: opt.Description, Description: opt.Description,
IssueLabels: opt.IssueLabels, IssueLabels: opt.IssueLabels,
@ -393,7 +393,7 @@ func Generate(ctx *context.APIContext) {
} }
} }
repo, err := repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, ctx.Repo.Repository, opts) repo, err := repo_service.GenerateRepository(ctx.Doer, ctxUser, ctx.Repo.Repository, opts)
if err != nil { if err != nil {
if repo_model.IsErrRepoAlreadyExist(err) { if repo_model.IsErrRepoAlreadyExist(err) {
ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.") ctx.Error(http.StatusConflict, "", "The repository with the same name already exists.")
@ -637,7 +637,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
} }
// Check if repository name has been changed and not just a case change // Check if repository name has been changed and not just a case change
if repo.LowerName != strings.ToLower(newRepoName) { if repo.LowerName != strings.ToLower(newRepoName) {
if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil { if err := repo_service.ChangeRepositoryName(ctx.Doer, repo, newRepoName); err != nil {
switch { switch {
case repo_model.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err):
ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err) ctx.Error(http.StatusUnprocessableEntity, fmt.Sprintf("repo name is already taken [name: %s]", newRepoName), err)
@ -714,7 +714,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err
repo.DefaultBranch = *opts.DefaultBranch repo.DefaultBranch = *opts.DefaultBranch
} }
if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil { if err := repo_service.UpdateRepository(repo, visibilityChanged); err != nil {
ctx.Error(http.StatusInternalServerError, "UpdateRepository", err) ctx.Error(http.StatusInternalServerError, "UpdateRepository", err)
return err return err
} }

View File

@ -368,7 +368,7 @@ func ServCommand(ctx *context.PrivateContext) {
return return
} }
repo, err = repo_service.PushCreateRepo(ctx, user, owner, results.RepoName) repo, err = repo_service.PushCreateRepo(user, owner, results.RepoName)
if err != nil { if err != nil {
log.Error("pushCreateRepo: %v", err) log.Error("pushCreateRepo: %v", err)
ctx.JSON(http.StatusNotFound, private.ErrServCommand{ ctx.JSON(http.StatusNotFound, private.ErrServCommand{

View File

@ -96,7 +96,7 @@ func UnadoptedRepos(ctx *context.Context) {
} }
ctx.Data["Keyword"] = q ctx.Data["Keyword"] = q
repoNames, count, err := repo_service.ListUnadoptedRepositories(ctx, q, &opts) repoNames, count, err := repo_service.ListUnadoptedRepositories(q, &opts)
if err != nil { if err != nil {
ctx.ServerError("ListUnadoptedRepositories", err) ctx.ServerError("ListUnadoptedRepositories", err)
} }
@ -148,7 +148,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
if has || !isDir { if has || !isDir {
// Fallthrough to failure mode // Fallthrough to failure mode
} else if action == "adopt" { } else if action == "adopt" {
if _, err := repo_service.AdoptRepository(ctx, ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ if _, err := repo_service.AdoptRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{
Name: dirSplit[1], Name: dirSplit[1],
IsPrivate: true, IsPrivate: true,
}); err != nil { }); err != nil {
@ -157,7 +157,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
} }
ctx.Flash.Success(ctx.Tr("repo.adopt_preexisting_success", dir)) ctx.Flash.Success(ctx.Tr("repo.adopt_preexisting_success", dir))
} else if action == "delete" { } else if action == "delete" {
if err := repo_service.DeleteUnadoptedRepository(ctx, ctx.Doer, ctxUser, dirSplit[1]); err != nil { if err := repo_service.DeleteUnadoptedRepository(ctx.Doer, ctxUser, dirSplit[1]); err != nil {
ctx.ServerError("repository.AdoptRepository", err) ctx.ServerError("repository.AdoptRepository", err)
return return
} }

View File

@ -137,7 +137,7 @@ func SettingsPost(ctx *context.Context) {
} }
for _, repo := range repos { for _, repo := range repos {
repo.OwnerName = org.Name repo.OwnerName = org.Name
if err := repo_service.UpdateRepository(ctx, repo, true); err != nil { if err := repo_service.UpdateRepository(repo, true); err != nil {
ctx.ServerError("UpdateRepository", err) ctx.ServerError("UpdateRepository", err)
return return
} }

View File

@ -91,7 +91,7 @@ func DeleteBranchPost(ctx *context.Context) {
defer redirect(ctx) defer redirect(ctx)
branchName := ctx.FormString("name") branchName := ctx.FormString("name")
if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil { if err := repo_service.DeleteBranch(ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
switch { switch {
case git.IsErrBranchNotExist(err): case git.IsErrBranchNotExist(err):
log.Debug("DeleteBranch: Can't delete non existing branch '%s'", branchName) log.Debug("DeleteBranch: Can't delete non existing branch '%s'", branchName)

View File

@ -276,7 +276,7 @@ func httpBase(ctx *context.Context) (h *serviceHandler) {
return return
} }
repo, err = repo_service.PushCreateRepo(ctx, ctx.Doer, owner, reponame) repo, err = repo_service.PushCreateRepo(ctx.Doer, owner, reponame)
if err != nil { if err != nil {
log.Error("pushCreateRepo: %v", err) log.Error("pushCreateRepo: %v", err)
ctx.Status(http.StatusNotFound) ctx.Status(http.StatusNotFound)

View File

@ -589,7 +589,7 @@ func RetrieveRepoReviewers(ctx *context.Context, repo *repo_model.Repository, is
return return
} }
teamReviewers, err = repo_service.GetReviewerTeams(ctx, repo) teamReviewers, err = repo_service.GetReviewerTeams(repo)
if err != nil { if err != nil {
ctx.ServerError("GetReviewerTeams", err) ctx.ServerError("GetReviewerTeams", err)
return return

View File

@ -1399,7 +1399,7 @@ func CleanUpPullRequest(ctx *context.Context) {
func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) { func deleteBranch(ctx *context.Context, pr *issues_model.PullRequest, gitRepo *git.Repository) {
fullBranchName := pr.HeadRepo.FullName() + ":" + pr.HeadBranch fullBranchName := pr.HeadRepo.FullName() + ":" + pr.HeadBranch
if err := repo_service.DeleteBranch(ctx, ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil { if err := repo_service.DeleteBranch(ctx.Doer, pr.HeadRepo, gitRepo, pr.HeadBranch); err != nil {
switch { switch {
case git.IsErrBranchNotExist(err): case git.IsErrBranchNotExist(err):
ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName)) ctx.Flash.Error(ctx.Tr("repo.branch.deletion_failed", fullBranchName))

View File

@ -248,14 +248,14 @@ func CreatePost(ctx *context.Context) {
return return
} }
repo, err = repo_service.GenerateRepository(ctx, ctx.Doer, ctxUser, templateRepo, opts) repo, err = repo_service.GenerateRepository(ctx.Doer, ctxUser, templateRepo, opts)
if err == nil { if err == nil {
log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name) log.Trace("Repository generated [%d]: %s/%s", repo.ID, ctxUser.Name, repo.Name)
ctx.Redirect(repo.Link()) ctx.Redirect(repo.Link())
return return
} }
} else { } else {
repo, err = repo_service.CreateRepository(ctx, ctx.Doer, ctxUser, repo_module.CreateRepoOptions{ repo, err = repo_service.CreateRepository(ctx.Doer, ctxUser, repo_module.CreateRepoOptions{
Name: form.RepoName, Name: form.RepoName,
Description: form.Description, Description: form.Description,
Gitignores: form.Gitignores, Gitignores: form.Gitignores,
@ -302,7 +302,7 @@ func Action(ctx *context.Context) {
ctx.Repo.Repository.Description = ctx.FormString("desc") ctx.Repo.Repository.Description = ctx.FormString("desc")
ctx.Repo.Repository.Website = ctx.FormString("site") ctx.Repo.Repository.Website = ctx.FormString("site")
err = repo_service.UpdateRepository(ctx, ctx.Repo.Repository, false) err = repo_service.UpdateRepository(ctx.Repo.Repository, false)
} }
if err != nil { if err != nil {

View File

@ -134,7 +134,7 @@ func SettingsPost(ctx *context.Context) {
ctx.Repo.GitRepo.Close() ctx.Repo.GitRepo.Close()
ctx.Repo.GitRepo = nil ctx.Repo.GitRepo = nil
} }
if err := repo_service.ChangeRepositoryName(ctx, ctx.Doer, repo, newRepoName); err != nil { if err := repo_service.ChangeRepositoryName(ctx.Doer, repo, newRepoName); err != nil {
ctx.Data["Err_RepoName"] = true ctx.Data["Err_RepoName"] = true
switch { switch {
case repo_model.IsErrRepoAlreadyExist(err): case repo_model.IsErrRepoAlreadyExist(err):
@ -183,7 +183,7 @@ func SettingsPost(ctx *context.Context) {
} }
repo.IsPrivate = form.Private repo.IsPrivate = form.Private
if err := repo_service.UpdateRepository(ctx, repo, visibilityChanged); err != nil { if err := repo_service.UpdateRepository(repo, visibilityChanged); err != nil {
ctx.ServerError("UpdateRepository", err) ctx.ServerError("UpdateRepository", err)
return return
} }
@ -541,7 +541,7 @@ func SettingsPost(ctx *context.Context) {
return return
} }
if repoChanged { if repoChanged {
if err := repo_service.UpdateRepository(ctx, repo, false); err != nil { if err := repo_service.UpdateRepository(repo, false); err != nil {
ctx.ServerError("UpdateRepository", err) ctx.ServerError("UpdateRepository", err)
return return
} }
@ -560,7 +560,7 @@ func SettingsPost(ctx *context.Context) {
} }
if changed { if changed {
if err := repo_service.UpdateRepository(ctx, repo, false); err != nil { if err := repo_service.UpdateRepository(repo, false); err != nil {
ctx.ServerError("UpdateRepository", err) ctx.ServerError("UpdateRepository", err)
return return
} }
@ -580,7 +580,7 @@ func SettingsPost(ctx *context.Context) {
repo.IsFsckEnabled = form.EnableHealthCheck repo.IsFsckEnabled = form.EnableHealthCheck
} }
if err := repo_service.UpdateRepository(ctx, repo, false); err != nil { if err := repo_service.UpdateRepository(repo, false); err != nil {
ctx.ServerError("UpdateRepository", err) ctx.ServerError("UpdateRepository", err)
return return
} }
@ -672,7 +672,7 @@ func SettingsPost(ctx *context.Context) {
return return
} }
if err := repo_service.ConvertForkToNormalRepository(ctx, repo); err != nil { if err := repo_service.ConvertForkToNormalRepository(repo); err != nil {
log.Error("Unable to convert repository %-v from fork. Error: %v", repo, err) log.Error("Unable to convert repository %-v from fork. Error: %v", repo, err)
ctx.ServerError("Convert Fork", err) ctx.ServerError("Convert Fork", err)
return return
@ -1244,7 +1244,7 @@ func UpdateAvatarSetting(ctx *context.Context, form forms.AvatarForm) error {
if !(st.IsImage() && !st.IsSvgImage()) { if !(st.IsImage() && !st.IsSvgImage()) {
return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image")) return errors.New(ctx.Tr("settings.uploaded_avatar_not_a_image"))
} }
if err = repo_service.UploadAvatar(ctx, ctxRepo, data); err != nil { if err = repo_service.UploadAvatar(ctxRepo, data); err != nil {
return fmt.Errorf("UploadAvatar: %w", err) return fmt.Errorf("UploadAvatar: %w", err)
} }
return nil return nil
@ -1264,7 +1264,7 @@ func SettingsAvatar(ctx *context.Context) {
// SettingsDeleteAvatar delete repository avatar // SettingsDeleteAvatar delete repository avatar
func SettingsDeleteAvatar(ctx *context.Context) { func SettingsDeleteAvatar(ctx *context.Context) {
if err := repo_service.DeleteAvatar(ctx, ctx.Repo.Repository); err != nil { if err := repo_service.DeleteAvatar(ctx.Repo.Repository); err != nil {
ctx.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err)) ctx.Flash.Error(fmt.Sprintf("DeleteAvatar: %v", err))
} }
ctx.Redirect(ctx.Repo.RepoLink + "/settings") ctx.Redirect(ctx.Repo.RepoLink + "/settings")

View File

@ -356,7 +356,7 @@ func RenameBranchPost(ctx *context.Context) {
return return
} }
msg, err := repository.RenameBranch(ctx, ctx.Repo.Repository, ctx.Doer, ctx.Repo.GitRepo, form.From, form.To) msg, err := repository.RenameBranch(ctx.Repo.Repository, ctx.Doer, ctx.Repo.GitRepo, form.From, form.To)
if err != nil { if err != nil {
ctx.ServerError("RenameBranch", err) ctx.ServerError("RenameBranch", err)
return return

View File

@ -45,7 +45,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
if has || !isDir { if has || !isDir {
// Fallthrough to failure mode // Fallthrough to failure mode
} else if action == "adopt" && allowAdopt { } else if action == "adopt" && allowAdopt {
if _, err := repo_service.AdoptRepository(ctx, ctxUser, ctxUser, repo_module.CreateRepoOptions{ if _, err := repo_service.AdoptRepository(ctxUser, ctxUser, repo_module.CreateRepoOptions{
Name: dir, Name: dir,
IsPrivate: true, IsPrivate: true,
}); err != nil { }); err != nil {
@ -54,7 +54,7 @@ func AdoptOrDeleteRepository(ctx *context.Context) {
} }
ctx.Flash.Success(ctx.Tr("repo.adopt_preexisting_success", dir)) ctx.Flash.Success(ctx.Tr("repo.adopt_preexisting_success", dir))
} else if action == "delete" && allowDelete { } else if action == "delete" && allowDelete {
if err := repo_service.DeleteUnadoptedRepository(ctx, ctxUser, ctxUser, dir); err != nil { if err := repo_service.DeleteUnadoptedRepository(ctxUser, ctxUser, dir); err != nil {
ctx.ServerError("repository.AdoptRepository", err) ctx.ServerError("repository.AdoptRepository", err)
return return
} }

View File

@ -26,7 +26,7 @@ import (
) )
// AdoptRepository adopts pre-existing repository files for the user/organization. // AdoptRepository adopts pre-existing repository files for the user/organization.
func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) { func AdoptRepository(doer, u *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) {
if !doer.IsAdmin && !u.CanCreateRepo() { if !doer.IsAdmin && !u.CanCreateRepo() {
return nil, repo_model.ErrReachLimitOfRepo{ return nil, repo_model.ErrReachLimitOfRepo{
Limit: u.MaxRepoCreation, Limit: u.MaxRepoCreation,
@ -53,7 +53,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts repo_mo
IsEmpty: !opts.AutoInit, IsEmpty: !opts.AutoInit,
} }
if err := db.WithTx(ctx, func(ctx context.Context) error { if err := db.WithTx(db.DefaultContext, func(ctx context.Context) error {
repoPath := repo_model.RepoPath(u.Name, repo.Name) repoPath := repo_model.RepoPath(u.Name, repo.Name)
isExist, err := util.IsExist(repoPath) isExist, err := util.IsExist(repoPath)
if err != nil { if err != nil {
@ -95,7 +95,7 @@ func AdoptRepository(ctx context.Context, doer, u *user_model.User, opts repo_mo
return nil, err return nil, err
} }
notification.NotifyCreateRepository(ctx, doer, u, repo) notification.NotifyCreateRepository(db.DefaultContext, doer, u, repo)
return repo, nil return repo, nil
} }
@ -188,7 +188,7 @@ func adoptRepository(ctx context.Context, repoPath string, u *user_model.User, r
} }
// DeleteUnadoptedRepository deletes unadopted repository files from the filesystem // DeleteUnadoptedRepository deletes unadopted repository files from the filesystem
func DeleteUnadoptedRepository(ctx context.Context, doer, u *user_model.User, repoName string) error { func DeleteUnadoptedRepository(doer, u *user_model.User, repoName string) error {
if err := repo_model.IsUsableRepoName(repoName); err != nil { if err := repo_model.IsUsableRepoName(repoName); err != nil {
return err return err
} }
@ -206,7 +206,7 @@ func DeleteUnadoptedRepository(ctx context.Context, doer, u *user_model.User, re
} }
} }
if exist, err := repo_model.IsRepositoryExist(ctx, u, repoName); err != nil { if exist, err := repo_model.IsRepositoryExist(db.DefaultContext, u, repoName); err != nil {
return err return err
} else if exist { } else if exist {
return repo_model.ErrRepoAlreadyExist{ return repo_model.ErrRepoAlreadyExist{
@ -232,11 +232,11 @@ func (unadopted *unadoptedRepositories) add(repository string) {
unadopted.index++ unadopted.index++
} }
func checkUnadoptedRepositories(ctx context.Context, userName string, repoNamesToCheck []string, unadopted *unadoptedRepositories) error { func checkUnadoptedRepositories(userName string, repoNamesToCheck []string, unadopted *unadoptedRepositories) error {
if len(repoNamesToCheck) == 0 { if len(repoNamesToCheck) == 0 {
return nil return nil
} }
ctxUser, err := user_model.GetUserByName(ctx, userName) ctxUser, err := user_model.GetUserByName(db.DefaultContext, userName)
if err != nil { if err != nil {
if user_model.IsErrUserNotExist(err) { if user_model.IsErrUserNotExist(err) {
log.Debug("Missing user: %s", userName) log.Debug("Missing user: %s", userName)
@ -271,7 +271,7 @@ func checkUnadoptedRepositories(ctx context.Context, userName string, repoNamesT
} }
// ListUnadoptedRepositories lists all the unadopted repositories that match the provided query // ListUnadoptedRepositories lists all the unadopted repositories that match the provided query
func ListUnadoptedRepositories(ctx context.Context, query string, opts *db.ListOptions) ([]string, int, error) { func ListUnadoptedRepositories(query string, opts *db.ListOptions) ([]string, int, error) {
globUser, _ := glob.Compile("*") globUser, _ := glob.Compile("*")
globRepo, _ := glob.Compile("*") globRepo, _ := glob.Compile("*")
@ -315,7 +315,7 @@ func ListUnadoptedRepositories(ctx context.Context, query string, opts *db.ListO
if !strings.ContainsRune(path[len(root)+1:], filepath.Separator) { if !strings.ContainsRune(path[len(root)+1:], filepath.Separator) {
// Got a new user // Got a new user
if err = checkUnadoptedRepositories(ctx, userName, repoNamesToCheck, unadopted); err != nil { if err = checkUnadoptedRepositories(userName, repoNamesToCheck, unadopted); err != nil {
return err return err
} }
repoNamesToCheck = repoNamesToCheck[:0] repoNamesToCheck = repoNamesToCheck[:0]
@ -338,7 +338,7 @@ func ListUnadoptedRepositories(ctx context.Context, query string, opts *db.ListO
repoNamesToCheck = append(repoNamesToCheck, name) repoNamesToCheck = append(repoNamesToCheck, name)
if len(repoNamesToCheck) >= setting.Database.IterateBufferSize { if len(repoNamesToCheck) >= setting.Database.IterateBufferSize {
if err = checkUnadoptedRepositories(ctx, userName, repoNamesToCheck, unadopted); err != nil { if err = checkUnadoptedRepositories(userName, repoNamesToCheck, unadopted); err != nil {
return err return err
} }
repoNamesToCheck = repoNamesToCheck[:0] repoNamesToCheck = repoNamesToCheck[:0]
@ -349,7 +349,7 @@ func ListUnadoptedRepositories(ctx context.Context, query string, opts *db.ListO
return nil, 0, err return nil, 0, err
} }
if err := checkUnadoptedRepositories(ctx, userName, repoNamesToCheck, unadopted); err != nil { if err := checkUnadoptedRepositories(userName, repoNamesToCheck, unadopted); err != nil {
return nil, 0, err return nil, 0, err
} }

View File

@ -39,7 +39,7 @@ func TestCheckUnadoptedRepositories(t *testing.T) {
// Non existent user // Non existent user
// //
unadopted := &unadoptedRepositories{start: 0, end: 100} unadopted := &unadoptedRepositories{start: 0, end: 100}
err := checkUnadoptedRepositories(db.DefaultContext, "notauser", []string{"repo"}, unadopted) err := checkUnadoptedRepositories("notauser", []string{"repo"}, unadopted)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 0, len(unadopted.repositories)) assert.Equal(t, 0, len(unadopted.repositories))
// //
@ -50,14 +50,14 @@ func TestCheckUnadoptedRepositories(t *testing.T) {
repoName := "repo2" repoName := "repo2"
unadoptedRepoName := "unadopted" unadoptedRepoName := "unadopted"
unadopted = &unadoptedRepositories{start: 0, end: 100} unadopted = &unadoptedRepositories{start: 0, end: 100}
err = checkUnadoptedRepositories(db.DefaultContext, userName, []string{repoName, unadoptedRepoName}, unadopted) err = checkUnadoptedRepositories(userName, []string{repoName, unadoptedRepoName}, unadopted)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, []string{path.Join(userName, unadoptedRepoName)}, unadopted.repositories) assert.Equal(t, []string{path.Join(userName, unadoptedRepoName)}, unadopted.repositories)
// //
// Existing (adopted) repository is not returned // Existing (adopted) repository is not returned
// //
unadopted = &unadoptedRepositories{start: 0, end: 100} unadopted = &unadoptedRepositories{start: 0, end: 100}
err = checkUnadoptedRepositories(db.DefaultContext, userName, []string{repoName}, unadopted) err = checkUnadoptedRepositories(userName, []string{repoName}, unadopted)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 0, len(unadopted.repositories)) assert.Equal(t, 0, len(unadopted.repositories))
assert.Equal(t, 0, unadopted.index) assert.Equal(t, 0, unadopted.index)
@ -72,13 +72,13 @@ func TestListUnadoptedRepositories_ListOptions(t *testing.T) {
} }
opts := db.ListOptions{Page: 1, PageSize: 1} opts := db.ListOptions{Page: 1, PageSize: 1}
repoNames, count, err := ListUnadoptedRepositories(db.DefaultContext, "", &opts) repoNames, count, err := ListUnadoptedRepositories("", &opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 2, count) assert.Equal(t, 2, count)
assert.Equal(t, unadoptedList[0], repoNames[0]) assert.Equal(t, unadoptedList[0], repoNames[0])
opts = db.ListOptions{Page: 2, PageSize: 1} opts = db.ListOptions{Page: 2, PageSize: 1}
repoNames, count, err = ListUnadoptedRepositories(db.DefaultContext, "", &opts) repoNames, count, err = ListUnadoptedRepositories("", &opts)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, 2, count) assert.Equal(t, 2, count)
assert.Equal(t, unadoptedList[1], repoNames[0]) assert.Equal(t, unadoptedList[1], repoNames[0])

View File

@ -20,7 +20,7 @@ import (
// UploadAvatar saves custom avatar for repository. // UploadAvatar saves custom avatar for repository.
// FIXME: split uploads to different subdirs in case we have massive number of repos. // FIXME: split uploads to different subdirs in case we have massive number of repos.
func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte) error { func UploadAvatar(repo *repo_model.Repository, data []byte) error {
m, err := avatar.Prepare(data) m, err := avatar.Prepare(data)
if err != nil { if err != nil {
return err return err
@ -31,7 +31,7 @@ func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte)
return nil return nil
} }
ctx, committer, err := db.TxContext(ctx) ctx, committer, err := db.TxContext(db.DefaultContext)
if err != nil { if err != nil {
return err return err
} }
@ -65,7 +65,7 @@ func UploadAvatar(ctx context.Context, repo *repo_model.Repository, data []byte)
} }
// DeleteAvatar deletes the repos's custom avatar. // DeleteAvatar deletes the repos's custom avatar.
func DeleteAvatar(ctx context.Context, repo *repo_model.Repository) error { func DeleteAvatar(repo *repo_model.Repository) error {
// Avatar not exists // Avatar not exists
if len(repo.Avatar) == 0 { if len(repo.Avatar) == 0 {
return nil return nil
@ -74,7 +74,7 @@ func DeleteAvatar(ctx context.Context, repo *repo_model.Repository) error {
avatarPath := repo.CustomAvatarRelativePath() avatarPath := repo.CustomAvatarRelativePath()
log.Trace("DeleteAvatar[%d]: %s", repo.ID, avatarPath) log.Trace("DeleteAvatar[%d]: %s", repo.ID, avatarPath)
ctx, committer, err := db.TxContext(ctx) ctx, committer, err := db.TxContext(db.DefaultContext)
if err != nil { if err != nil {
return err return err
} }
@ -102,7 +102,7 @@ func RemoveRandomAvatars(ctx context.Context) error {
} }
stringifiedID := strconv.FormatInt(repository.ID, 10) stringifiedID := strconv.FormatInt(repository.ID, 10)
if repository.Avatar == stringifiedID { if repository.Avatar == stringifiedID {
return DeleteAvatar(ctx, repository) return DeleteAvatar(repository)
} }
return nil return nil
}) })

View File

@ -9,7 +9,6 @@ import (
"image/png" "image/png"
"testing" "testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/avatar" "code.gitea.io/gitea/modules/avatar"
@ -26,7 +25,7 @@ func TestUploadAvatar(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) err := UploadAvatar(repo, buff.Bytes())
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar) assert.Equal(t, avatar.HashAvatar(10, buff.Bytes()), repo.Avatar)
} }
@ -40,7 +39,7 @@ func TestUploadBigAvatar(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) err := UploadAvatar(repo, buff.Bytes())
assert.Error(t, err) assert.Error(t, err)
} }
@ -53,10 +52,10 @@ func TestDeleteAvatar(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(db.DefaultContext, repo, buff.Bytes()) err := UploadAvatar(repo, buff.Bytes())
assert.NoError(t, err) assert.NoError(t, err)
err = DeleteAvatar(db.DefaultContext, repo) err = DeleteAvatar(repo)
assert.NoError(t, err) assert.NoError(t, err)
assert.Equal(t, "", repo.Avatar) assert.Equal(t, "", repo.Avatar)

View File

@ -10,6 +10,7 @@ import (
"strings" "strings"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git" git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
@ -105,7 +106,7 @@ func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo
} }
// RenameBranch rename a branch // RenameBranch rename a branch
func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, gitRepo *git.Repository, from, to string) (string, error) { func RenameBranch(repo *repo_model.Repository, doer *user_model.User, gitRepo *git.Repository, from, to string) (string, error) {
if from == to { if from == to {
return "target_exist", nil return "target_exist", nil
} }
@ -118,7 +119,7 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
return "from_not_exist", nil return "from_not_exist", nil
} }
if err := git_model.RenameBranch(ctx, repo, from, to, func(isDefault bool) error { if err := git_model.RenameBranch(db.DefaultContext, repo, from, to, func(isDefault bool) error {
err2 := gitRepo.RenameBranch(from, to) err2 := gitRepo.RenameBranch(from, to)
if err2 != nil { if err2 != nil {
return err2 return err2
@ -140,8 +141,8 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
return "", err return "", err
} }
notification.NotifyDeleteRef(ctx, doer, repo, "branch", git.BranchPrefix+from) notification.NotifyDeleteRef(db.DefaultContext, doer, repo, "branch", git.BranchPrefix+from)
notification.NotifyCreateRef(ctx, doer, repo, "branch", git.BranchPrefix+to, refID) notification.NotifyCreateRef(db.DefaultContext, doer, repo, "branch", git.BranchPrefix+to, refID)
return "", nil return "", nil
} }
@ -152,12 +153,12 @@ var (
) )
// DeleteBranch delete branch // DeleteBranch delete branch
func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string) error { func DeleteBranch(doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string) error {
if branchName == repo.DefaultBranch { if branchName == repo.DefaultBranch {
return ErrBranchIsDefault return ErrBranchIsDefault
} }
isProtected, err := git_model.IsBranchProtected(ctx, repo.ID, branchName) isProtected, err := git_model.IsBranchProtected(db.DefaultContext, repo.ID, branchName)
if err != nil { if err != nil {
return err return err
} }
@ -194,7 +195,7 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R
log.Error("Update: %v", err) log.Error("Update: %v", err)
} }
if err := git_model.AddDeletedBranch(ctx, repo.ID, branchName, commit.ID.String(), doer.ID); err != nil { if err := git_model.AddDeletedBranch(db.DefaultContext, repo.ID, branchName, commit.ID.String(), doer.ID); err != nil {
log.Warn("AddDeletedBranch: %v", err) log.Warn("AddDeletedBranch: %v", err)
} }

View File

@ -189,8 +189,8 @@ func ForkRepository(ctx context.Context, doer, owner *user_model.User, opts Fork
} }
// ConvertForkToNormalRepository convert the provided repo from a forked repo to normal repo // ConvertForkToNormalRepository convert the provided repo from a forked repo to normal repo
func ConvertForkToNormalRepository(ctx context.Context, repo *repo_model.Repository) error { func ConvertForkToNormalRepository(repo *repo_model.Repository) error {
err := db.WithTx(ctx, func(ctx context.Context) error { err := db.WithTx(db.DefaultContext, func(ctx context.Context) error {
repo, err := repo_model.GetRepositoryByID(ctx, repo.ID) repo, err := repo_model.GetRepositoryByID(ctx, repo.ID)
if err != nil { if err != nil {
return err return err

View File

@ -80,7 +80,6 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("PushUpdates: %s/%s", optsList[0].RepoUserName, optsList[0].RepoName)) ctx, _, finished := process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("PushUpdates: %s/%s", optsList[0].RepoUserName, optsList[0].RepoName))
defer finished() defer finished()
ctx = cache.WithCacheContext(ctx)
repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, optsList[0].RepoUserName, optsList[0].RepoName) repo, err := repo_model.GetRepositoryByOwnerAndName(ctx, optsList[0].RepoUserName, optsList[0].RepoName)
if err != nil { if err != nil {
@ -123,7 +122,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
tagName := opts.TagName() tagName := opts.TagName()
if opts.IsDelRef() { if opts.IsDelRef() {
notification.NotifyPushCommits( notification.NotifyPushCommits(
ctx, pusher, repo, db.DefaultContext, pusher, repo,
&repo_module.PushUpdateOptions{ &repo_module.PushUpdateOptions{
RefFullName: git.TagPrefix + tagName, RefFullName: git.TagPrefix + tagName,
OldCommitID: opts.OldCommitID, OldCommitID: opts.OldCommitID,
@ -131,7 +130,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
}, repo_module.NewPushCommits()) }, repo_module.NewPushCommits())
delTags = append(delTags, tagName) delTags = append(delTags, tagName)
notification.NotifyDeleteRef(ctx, pusher, repo, "tag", opts.RefFullName) notification.NotifyDeleteRef(db.DefaultContext, pusher, repo, "tag", opts.RefFullName)
} else { // is new tag } else { // is new tag
newCommit, err := gitRepo.GetCommit(opts.NewCommitID) newCommit, err := gitRepo.GetCommit(opts.NewCommitID)
if err != nil { if err != nil {
@ -143,7 +142,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
commits.CompareURL = repo.ComposeCompareURL(git.EmptySHA, opts.NewCommitID) commits.CompareURL = repo.ComposeCompareURL(git.EmptySHA, opts.NewCommitID)
notification.NotifyPushCommits( notification.NotifyPushCommits(
ctx, pusher, repo, db.DefaultContext, pusher, repo,
&repo_module.PushUpdateOptions{ &repo_module.PushUpdateOptions{
RefFullName: git.TagPrefix + tagName, RefFullName: git.TagPrefix + tagName,
OldCommitID: git.EmptySHA, OldCommitID: git.EmptySHA,
@ -151,7 +150,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
}, commits) }, commits)
addTags = append(addTags, tagName) addTags = append(addTags, tagName)
notification.NotifyCreateRef(ctx, pusher, repo, "tag", opts.RefFullName, opts.NewCommitID) notification.NotifyCreateRef(db.DefaultContext, pusher, repo, "tag", opts.RefFullName, opts.NewCommitID)
} }
} else if opts.IsBranch() { // If is branch reference } else if opts.IsBranch() { // If is branch reference
if pusher == nil || pusher.ID != opts.PusherID { if pusher == nil || pusher.ID != opts.PusherID {
@ -191,7 +190,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
} }
} }
// Update the is empty and default_branch columns // Update the is empty and default_branch columns
if err := repo_model.UpdateRepositoryCols(ctx, repo, "default_branch", "is_empty"); err != nil { if err := repo_model.UpdateRepositoryCols(db.DefaultContext, repo, "default_branch", "is_empty"); err != nil {
return fmt.Errorf("UpdateRepositoryCols: %w", err) return fmt.Errorf("UpdateRepositoryCols: %w", err)
} }
} }
@ -200,7 +199,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
if err != nil { if err != nil {
return fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err) return fmt.Errorf("newCommit.CommitsBeforeLimit: %w", err)
} }
notification.NotifyCreateRef(ctx, pusher, repo, "branch", opts.RefFullName, opts.NewCommitID) notification.NotifyCreateRef(db.DefaultContext, pusher, repo, "branch", opts.RefFullName, opts.NewCommitID)
} else { } else {
l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID) l, err = newCommit.CommitsBeforeUntil(opts.OldCommitID)
if err != nil { if err != nil {
@ -260,7 +259,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum] commits.Commits = commits.Commits[:setting.UI.FeedMaxCommitNum]
} }
notification.NotifyPushCommits(ctx, pusher, repo, opts, commits) notification.NotifyPushCommits(db.DefaultContext, pusher, repo, opts, commits)
if err = git_model.RemoveDeletedBranchByName(ctx, repo.ID, branch); err != nil { if err = git_model.RemoveDeletedBranchByName(ctx, repo.ID, branch); err != nil {
log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err) log.Error("models.RemoveDeletedBranch %s/%s failed: %v", repo.ID, branch, err)
@ -271,7 +270,7 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err) log.Error("repo_module.CacheRef %s/%s failed: %v", repo.ID, branch, err)
} }
} else { } else {
notification.NotifyDeleteRef(ctx, pusher, repo, "branch", opts.RefFullName) notification.NotifyDeleteRef(db.DefaultContext, pusher, repo, "branch", opts.RefFullName)
if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil { if err = pull_service.CloseBranchPulls(pusher, repo.ID, branch); err != nil {
// close all related pulls // close all related pulls
log.Error("close related pull request failed: %v", err) log.Error("close related pull request failed: %v", err)
@ -279,14 +278,14 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
} }
// Even if user delete a branch on a repository which he didn't watch, he will be watch that. // Even if user delete a branch on a repository which he didn't watch, he will be watch that.
if err = repo_model.WatchIfAuto(ctx, opts.PusherID, repo.ID, true); err != nil { if err = repo_model.WatchIfAuto(db.DefaultContext, opts.PusherID, repo.ID, true); err != nil {
log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err) log.Warn("Fail to perform auto watch on user %v for repo %v: %v", opts.PusherID, repo.ID, err)
} }
} else { } else {
log.Trace("Non-tag and non-branch commits pushed.") log.Trace("Non-tag and non-branch commits pushed.")
} }
} }
if err := PushUpdateAddDeleteTags(ctx, repo, gitRepo, addTags, delTags); err != nil { if err := PushUpdateAddDeleteTags(repo, gitRepo, addTags, delTags); err != nil {
return fmt.Errorf("PushUpdateAddDeleteTags: %w", err) return fmt.Errorf("PushUpdateAddDeleteTags: %w", err)
} }
@ -299,8 +298,8 @@ func pushUpdates(optsList []*repo_module.PushUpdateOptions) error {
} }
// PushUpdateAddDeleteTags updates a number of added and delete tags // PushUpdateAddDeleteTags updates a number of added and delete tags
func PushUpdateAddDeleteTags(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, addTags, delTags []string) error { func PushUpdateAddDeleteTags(repo *repo_model.Repository, gitRepo *git.Repository, addTags, delTags []string) error {
return db.WithTx(ctx, func(ctx context.Context) error { return db.WithTx(db.DefaultContext, func(ctx context.Context) error {
if err := repo_model.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil { if err := repo_model.PushUpdateDeleteTagsContext(ctx, repo, delTags); err != nil {
return err return err
} }

View File

@ -24,14 +24,14 @@ import (
) )
// CreateRepository creates a repository for the user/organization. // CreateRepository creates a repository for the user/organization.
func CreateRepository(ctx context.Context, doer, owner *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) { func CreateRepository(doer, owner *user_model.User, opts repo_module.CreateRepoOptions) (*repo_model.Repository, error) {
repo, err := repo_module.CreateRepository(doer, owner, opts) repo, err := repo_module.CreateRepository(doer, owner, opts)
if err != nil { if err != nil {
// No need to rollback here we should do this in CreateRepository... // No need to rollback here we should do this in CreateRepository...
return nil, err return nil, err
} }
notification.NotifyCreateRepository(ctx, doer, owner, repo) notification.NotifyCreateRepository(db.DefaultContext, doer, owner, repo)
return repo, nil return repo, nil
} }
@ -55,10 +55,10 @@ func DeleteRepository(ctx context.Context, doer *user_model.User, repo *repo_mod
} }
// PushCreateRepo creates a repository when a new repository is pushed to an appropriate namespace // PushCreateRepo creates a repository when a new repository is pushed to an appropriate namespace
func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoName string) (*repo_model.Repository, error) { func PushCreateRepo(authUser, owner *user_model.User, repoName string) (*repo_model.Repository, error) {
if !authUser.IsAdmin { if !authUser.IsAdmin {
if owner.IsOrganization() { if owner.IsOrganization() {
if ok, err := organization.CanCreateOrgRepo(ctx, owner.ID, authUser.ID); err != nil { if ok, err := organization.CanCreateOrgRepo(db.DefaultContext, owner.ID, authUser.ID); err != nil {
return nil, err return nil, err
} else if !ok { } else if !ok {
return nil, fmt.Errorf("cannot push-create repository for org") return nil, fmt.Errorf("cannot push-create repository for org")
@ -68,7 +68,7 @@ func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoN
} }
} }
repo, err := CreateRepository(ctx, authUser, owner, repo_module.CreateRepoOptions{ repo, err := CreateRepository(authUser, owner, repo_module.CreateRepoOptions{
Name: repoName, Name: repoName,
IsPrivate: setting.Repository.DefaultPushCreatePrivate, IsPrivate: setting.Repository.DefaultPushCreatePrivate,
}) })
@ -88,8 +88,8 @@ func Init() error {
} }
// UpdateRepository updates a repository // UpdateRepository updates a repository
func UpdateRepository(ctx context.Context, repo *repo_model.Repository, visibilityChanged bool) (err error) { func UpdateRepository(repo *repo_model.Repository, visibilityChanged bool) (err error) {
ctx, committer, err := db.TxContext(ctx) ctx, committer, err := db.TxContext(db.DefaultContext)
if err != nil { if err != nil {
return err return err
} }

View File

@ -4,21 +4,20 @@
package repository package repository
import ( import (
"context" "code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/perm"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
) )
// GetReviewerTeams get all teams can be requested to review // GetReviewerTeams get all teams can be requested to review
func GetReviewerTeams(ctx context.Context, repo *repo_model.Repository) ([]*organization.Team, error) { func GetReviewerTeams(repo *repo_model.Repository) ([]*organization.Team, error) {
if err := repo.LoadOwner(ctx); err != nil { if err := repo.LoadOwner(db.DefaultContext); err != nil {
return nil, err return nil, err
} }
if !repo.Owner.IsOrganization() { if !repo.Owner.IsOrganization() {
return nil, nil return nil, nil
} }
return organization.GetTeamsWithAccessToRepo(ctx, repo.OwnerID, repo.ID, perm.AccessModeRead) return organization.GetTeamsWithAccessToRepo(db.DefaultContext, repo.OwnerID, repo.ID, perm.AccessModeRead)
} }

View File

@ -6,7 +6,6 @@ package repository
import ( import (
"testing" "testing"
"code.gitea.io/gitea/models/db"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/models/unittest"
@ -17,12 +16,12 @@ func TestRepoGetReviewerTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase()) assert.NoError(t, unittest.PrepareTestDatabase())
repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}) repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
teams, err := GetReviewerTeams(db.DefaultContext, repo2) teams, err := GetReviewerTeams(repo2)
assert.NoError(t, err) assert.NoError(t, err)
assert.Empty(t, teams) assert.Empty(t, teams)
repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
teams, err = GetReviewerTeams(db.DefaultContext, repo3) teams, err = GetReviewerTeams(repo3)
assert.NoError(t, err) assert.NoError(t, err)
assert.Len(t, teams, 2) assert.Len(t, teams, 2)
} }

View File

@ -40,7 +40,7 @@ func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_m
} }
// GenerateRepository generates a repository from a template // GenerateRepository generates a repository from a template
func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templateRepo *repo_model.Repository, opts repo_module.GenerateRepoOptions) (_ *repo_model.Repository, err error) { func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.Repository, opts repo_module.GenerateRepoOptions) (_ *repo_model.Repository, err error) {
if !doer.IsAdmin && !owner.CanCreateRepo() { if !doer.IsAdmin && !owner.CanCreateRepo() {
return nil, repo_model.ErrReachLimitOfRepo{ return nil, repo_model.ErrReachLimitOfRepo{
Limit: owner.MaxRepoCreation, Limit: owner.MaxRepoCreation,
@ -48,7 +48,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
} }
var generateRepo *repo_model.Repository var generateRepo *repo_model.Repository
if err = db.WithTx(ctx, func(ctx context.Context) error { if err = db.WithTx(db.DefaultContext, func(ctx context.Context) error {
generateRepo, err = repo_module.GenerateRepository(ctx, doer, owner, templateRepo, opts) generateRepo, err = repo_module.GenerateRepository(ctx, doer, owner, templateRepo, opts)
if err != nil { if err != nil {
return err return err
@ -101,7 +101,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
return nil, err return nil, err
} }
notification.NotifyCreateRepository(ctx, doer, owner, generateRepo) notification.NotifyCreateRepository(db.DefaultContext, doer, owner, generateRepo)
return generateRepo, nil return generateRepo, nil
} }

View File

@ -8,6 +8,7 @@ import (
"fmt" "fmt"
"code.gitea.io/gitea/models" "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/organization" "code.gitea.io/gitea/models/organization"
"code.gitea.io/gitea/models/perm" "code.gitea.io/gitea/models/perm"
access_model "code.gitea.io/gitea/models/perm/access" access_model "code.gitea.io/gitea/models/perm/access"
@ -60,7 +61,7 @@ func TransferOwnership(ctx context.Context, doer, newOwner *user_model.User, rep
} }
// ChangeRepositoryName changes all corresponding setting from old repository name to new one. // ChangeRepositoryName changes all corresponding setting from old repository name to new one.
func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, newRepoName string) error { func ChangeRepositoryName(doer *user_model.User, repo *repo_model.Repository, newRepoName string) error {
log.Trace("ChangeRepositoryName: %s/%s -> %s", doer.Name, repo.Name, newRepoName) log.Trace("ChangeRepositoryName: %s/%s -> %s", doer.Name, repo.Name, newRepoName)
oldRepoName := repo.Name oldRepoName := repo.Name
@ -77,7 +78,7 @@ func ChangeRepositoryName(ctx context.Context, doer *user_model.User, repo *repo
repoWorkingPool.CheckOut(fmt.Sprint(repo.ID)) repoWorkingPool.CheckOut(fmt.Sprint(repo.ID))
repo.Name = newRepoName repo.Name = newRepoName
notification.NotifyRenameRepository(ctx, doer, repo, oldRepoName) notification.NotifyRenameRepository(db.DefaultContext, doer, repo, oldRepoName)
return nil return nil
} }

View File

@ -46,32 +46,49 @@
<div class="ui dropdown icon button" title="{{.locale.Tr "home.filter"}}"> <div class="ui dropdown icon button" title="{{.locale.Tr "home.filter"}}">
<i class="icon gt-df gt-ac gt-jc gt-m-0">{{svg "octicon-filter" 16}}</i> <i class="icon gt-df gt-ac gt-jc gt-m-0">{{svg "octicon-filter" 16}}</i>
<div class="menu"> <div class="menu">
<a class="item" @click="toggleArchivedFilter()"> <div class="item">
<div class="ui checkbox" <a @click="toggleArchivedFilter()">
ref="checkboxArchivedFilter" <div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_both_archived_unarchived"}}" v-if="archivedFilter === 'both'">
data-title-both="{{.locale.Tr "home.show_both_archived_unarchived"}}" <input type="checkbox">
data-title-unarchived="{{.locale.Tr "home.show_only_unarchived"}}" <label>
data-title-archived="{{.locale.Tr "home.show_only_archived"}}" {{svg "octicon-archive" 16 "gt-mr-2"}}
:title="checkboxArchivedFilterTitle" {{.locale.Tr "home.show_archived"}}
> </label>
<!--the "hidden" is necessary to make the checkbox work without Fomantic UI js, </div>
otherwise if the "input" handles click event for intermediate status, it breaks the internal state--> <div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_only_unarchived"}}" v-if="archivedFilter === 'unarchived'">
<input type="checkbox" class="hidden" v-bind.prop="checkboxArchivedFilterProps"> <input type="checkbox">
<label>
{{svg "octicon-archive" 16 "gt-mr-2"}}
{{.locale.Tr "home.show_archived"}}
</label>
</div>
<div class="ui checkbox" id="archivedFilterCheckbox" title="{{.locale.Tr "home.show_only_archived"}}" v-if="archivedFilter === 'archived'">
<input type="checkbox">
<label> <label>
{{svg "octicon-archive" 16 "gt-mr-2"}} {{svg "octicon-archive" 16 "gt-mr-2"}}
{{.locale.Tr "home.show_archived"}} {{.locale.Tr "home.show_archived"}}
</label> </label>
</div> </div>
</a> </a>
<a class="item" @click="togglePrivateFilter()"> </div>
<div class="ui checkbox" <div class="item">
ref="checkboxPrivateFilter" <a @click="togglePrivateFilter()">
data-title-both="{{.locale.Tr "home.show_both_private_public"}}" <div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_both_private_public"}}" v-if="privateFilter === 'both'">
data-title-public="{{.locale.Tr "home.show_only_public"}}" <input type="checkbox">
data-title-private="{{.locale.Tr "home.show_only_private"}}" <label>
:title="checkboxPrivateFilterTitle" {{svg "octicon-lock" 16 "gt-mr-2"}}
> {{.locale.Tr "home.show_private"}}
<input type="checkbox" class="hidden" v-bind.prop="checkboxPrivateFilterProps"> </label>
</div>
<div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_only_public"}}" v-if="privateFilter === 'public'">
<input type="checkbox">
<label>
{{svg "octicon-lock" 16 "gt-mr-2"}}
{{.locale.Tr "home.show_private"}}
</label>
</div>
<div class="ui checkbox" id="privateFilterCheckbox" title="{{.locale.Tr "home.show_only_private"}}" v-if="privateFilter === 'private'">
<input type="checkbox">
<label> <label>
{{svg "octicon-lock" 16 "gt-mr-2"}} {{svg "octicon-lock" 16 "gt-mr-2"}}
{{.locale.Tr "home.show_private"}} {{.locale.Tr "home.show_private"}}
@ -81,6 +98,7 @@
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="ui secondary tiny pointing borderless menu center grid repos-filter"> <div class="ui secondary tiny pointing borderless menu center grid repos-filter">
<a class="item" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')"> <a class="item" :class="{active: reposFilter === 'all'}" @click="changeReposFilter('all')">
{{.locale.Tr "all"}} {{.locale.Tr "all"}}

View File

@ -356,7 +356,7 @@ func TestConflictChecking(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Create new clean repo to test conflict checking. // Create new clean repo to test conflict checking.
baseRepo, err := repo_service.CreateRepository(db.DefaultContext, user, user, repo_module.CreateRepoOptions{ baseRepo, err := repo_service.CreateRepository(user, user, repo_module.CreateRepoOptions{
Name: "conflict-checking", Name: "conflict-checking",
Description: "Tempo repo", Description: "Tempo repo",
AutoInit: true, AutoInit: true,

View File

@ -80,7 +80,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
} }
func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest { func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_model.PullRequest {
baseRepo, err := repo_service.CreateRepository(db.DefaultContext, actor, actor, repo_module.CreateRepoOptions{ baseRepo, err := repo_service.CreateRepository(actor, actor, repo_module.CreateRepoOptions{
Name: "repo-pr-update", Name: "repo-pr-update",
Description: "repo-tmp-pr-update description", Description: "repo-tmp-pr-update description",
AutoInit: true, AutoInit: true,

View File

@ -87,7 +87,6 @@ function initVueComponents(app) {
} }
return { return {
hasMounted: false, // accessing $refs in computed() need to wait for mounted
tab, tab,
repos: [], repos: [],
reposTotalCount: 0, reposTotalCount: 0,
@ -135,19 +134,7 @@ function initVueComponents(app) {
}, },
repoTypeCount() { repoTypeCount() {
return this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`]; return this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`];
}, }
checkboxArchivedFilterTitle() {
return this.hasMounted && this.$refs.checkboxArchivedFilter?.getAttribute(`data-title-${this.archivedFilter}`);
},
checkboxArchivedFilterProps() {
return {checked: this.archivedFilter === 'archived', indeterminate: this.archivedFilter === 'both'};
},
checkboxPrivateFilterTitle() {
return this.hasMounted && this.$refs.checkboxPrivateFilter?.getAttribute(`data-title-${this.privateFilter}`);
},
checkboxPrivateFilterProps() {
return {checked: this.privateFilter === 'private', indeterminate: this.privateFilter === 'both'};
},
}, },
mounted() { mounted() {
@ -157,11 +144,10 @@ function initVueComponents(app) {
initTooltip(elTooltip); initTooltip(elTooltip);
} }
$(el).find('.dropdown').dropdown(); $(el).find('.dropdown').dropdown();
this.setCheckboxes();
nextTick(() => { nextTick(() => {
this.$refs.search.focus(); this.$refs.search.focus();
}); });
this.hasMounted = true;
}, },
methods: { methods: {
@ -170,6 +156,39 @@ function initVueComponents(app) {
this.updateHistory(); this.updateHistory();
}, },
setCheckboxes() {
switch (this.archivedFilter) {
case 'unarchived':
$('#archivedFilterCheckbox').checkbox('set unchecked');
break;
case 'archived':
$('#archivedFilterCheckbox').checkbox('set checked');
break;
case 'both':
$('#archivedFilterCheckbox').checkbox('set indeterminate');
break;
default:
this.archivedFilter = 'unarchived';
$('#archivedFilterCheckbox').checkbox('set unchecked');
break;
}
switch (this.privateFilter) {
case 'public':
$('#privateFilterCheckbox').checkbox('set unchecked');
break;
case 'private':
$('#privateFilterCheckbox').checkbox('set checked');
break;
case 'both':
$('#privateFilterCheckbox').checkbox('set indeterminate');
break;
default:
this.privateFilter = 'both';
$('#privateFilterCheckbox').checkbox('set indeterminate');
break;
}
},
changeReposFilter(filter) { changeReposFilter(filter) {
this.reposFilter = filter; this.reposFilter = filter;
this.repos = []; this.repos = [];
@ -226,29 +245,45 @@ function initVueComponents(app) {
}, },
toggleArchivedFilter() { toggleArchivedFilter() {
if (this.archivedFilter === 'unarchived') { switch (this.archivedFilter) {
this.archivedFilter = 'archived'; case 'both':
} else if (this.archivedFilter === 'archived') {
this.archivedFilter = 'both';
} else { // including both
this.archivedFilter = 'unarchived'; this.archivedFilter = 'unarchived';
break;
case 'unarchived':
this.archivedFilter = 'archived';
break;
case 'archived':
this.archivedFilter = 'both';
break;
default:
this.archivedFilter = 'unarchived';
break;
} }
this.page = 1; this.page = 1;
this.repos = []; this.repos = [];
this.setCheckboxes();
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0; this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
this.searchRepos(); this.searchRepos();
}, },
togglePrivateFilter() { togglePrivateFilter() {
if (this.privateFilter === 'both') { switch (this.privateFilter) {
case 'both':
this.privateFilter = 'public'; this.privateFilter = 'public';
} else if (this.privateFilter === 'public') { break;
case 'public':
this.privateFilter = 'private'; this.privateFilter = 'private';
} else { // including private break;
case 'private':
this.privateFilter = 'both'; this.privateFilter = 'both';
break;
default:
this.privateFilter = 'both';
break;
} }
this.page = 1; this.page = 1;
this.repos = []; this.repos = [];
this.setCheckboxes();
this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0; this.counts[`${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`] = 0;
this.searchRepos(); this.searchRepos();
}, },