diff --git a/.gitignore b/.gitignore index 1ce2a87611e81..ad141c30cd9ad 100644 --- a/.gitignore +++ b/.gitignore @@ -71,6 +71,7 @@ cpu.out /tests/e2e/test-artifacts /tests/e2e/test-snapshots /tests/*.ini +/tests/**/*.git/**/*.sample /node_modules /yarn.lock /yarn-error.log diff --git a/MAINTAINERS b/MAINTAINERS index f920f71f63e83..ef416639b0fea 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -41,7 +41,7 @@ Patrick Schratz (@pat-s) Janis Estelmann (@KN4CK3R) Steven Kriegler (@justusbunsi) Jimmy Praet (@jpraet) -Leon Hofmeister (@delvh) +Leon Hofmeister (@delvh) Wim (@42wim) Jason Song (@wolfogre) Yarden Shoham (@yardenshoham) @@ -49,3 +49,4 @@ Yu Tian (@Zettat123) Eddie Yang <576951401@qq.com> (@yp05327) Dong Ge (@sillyguodong) Xinyi Gong (@HesterG) +wxiaoguang (@wxiaoguang) diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 3e7db196f721d..1b6ead5df654b 100644 --- a/assets/go-licenses.json +++ b/assets/go-licenses.json @@ -1004,6 +1004,11 @@ "path": "golang.org/x/crypto/LICENSE", "licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" }, + { + "name": "golang.org/x/image", + "path": "golang.org/x/image/LICENSE", + "licenseText": "Copyright (c) 2009 The Go Authors. All rights reserved.\n\nRedistribution and use in source and binary forms, with or without\nmodification, are permitted provided that the following conditions are\nmet:\n\n * Redistributions of source code must retain the above copyright\nnotice, this list of conditions and the following disclaimer.\n * Redistributions in binary form must reproduce the above\ncopyright notice, this list of conditions and the following disclaimer\nin the documentation and/or other materials provided with the\ndistribution.\n * Neither the name of Google Inc. nor the names of its\ncontributors may be used to endorse or promote products derived from\nthis software without specific prior written permission.\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR\nA PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT\nOWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\nSPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT\nLIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\nDATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\nTHEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE\nOF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n" + }, { "name": "golang.org/x/mod/semver", "path": "golang.org/x/mod/semver/LICENSE", diff --git a/go.mod b/go.mod index 944f6d2c918c8..92201f8e5e409 100644 --- a/go.mod +++ b/go.mod @@ -104,10 +104,11 @@ require ( github.com/yuin/goldmark-highlighting/v2 v2.0.0-20220924101305-151362477c87 github.com/yuin/goldmark-meta v1.1.0 golang.org/x/crypto v0.7.0 + golang.org/x/image v0.7.0 golang.org/x/net v0.8.0 golang.org/x/oauth2 v0.6.0 golang.org/x/sys v0.6.0 - golang.org/x/text v0.8.0 + golang.org/x/text v0.9.0 golang.org/x/tools v0.6.0 google.golang.org/grpc v1.53.0 google.golang.org/protobuf v1.28.1 diff --git a/go.sum b/go.sum index df57c65918b05..a331ec21e7b92 100644 --- a/go.sum +++ b/go.sum @@ -1331,6 +1331,8 @@ golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EH golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw= +golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1415,6 +1417,7 @@ golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.0.0-20220906165146-f3363e06e74c/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -1533,6 +1536,7 @@ golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= @@ -1540,6 +1544,7 @@ golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9sn golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20220722155259-a9ba230a4035/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= golang.org/x/term v0.6.0 h1:clScbb1cHjoCkyRbWwBEUZ5H/tIFu5TAXIqaZD0Gcjw= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -1551,8 +1556,9 @@ golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= diff --git a/models/migrations/base/testlogger.go b/models/migrations/base/testlogger.go index 7cbf4602be00e..80e672952a64b 100644 --- a/models/migrations/base/testlogger.go +++ b/models/migrations/base/testlogger.go @@ -165,11 +165,6 @@ func (log *TestLogger) Init(config string) error { return nil } -// Content returns the content accumulated in the content provider -func (log *TestLogger) Content() (string, error) { - return "", fmt.Errorf("not supported") -} - // Flush when log should be flushed func (log *TestLogger) Flush() { } diff --git a/models/user/user.go b/models/user/user.go index 5f152780bff04..053d6680cddea 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -62,7 +62,7 @@ const ( EmailNotificationsOnMention = "onmention" // EmailNotificationsDisabled indicates that the user would not like to be notified via email. EmailNotificationsDisabled = "disabled" - // EmailNotificationsEnabled indicates that the user would like to receive all email notifications and your own + // EmailNotificationsAndYourOwn indicates that the user would like to receive all email notifications and your own EmailNotificationsAndYourOwn = "andyourown" ) diff --git a/modules/avatar/avatar.go b/modules/avatar/avatar.go index 9ee926b059ba7..c166f144042a9 100644 --- a/modules/avatar/avatar.go +++ b/modules/avatar/avatar.go @@ -18,6 +18,8 @@ import ( "github.com/nfnt/resize" "github.com/oliamb/cutter" + + _ "golang.org/x/image/webp" // for processing webp images ) // AvatarSize returns avatar's size diff --git a/modules/log/buffer.go b/modules/log/buffer.go deleted file mode 100644 index 1eee2465f14ea..0000000000000 --- a/modules/log/buffer.go +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package log - -import ( - "bytes" - "sync" -) - -type bufferWriteCloser struct { - mu sync.Mutex - buffer bytes.Buffer -} - -func (b *bufferWriteCloser) Write(p []byte) (int, error) { - b.mu.Lock() - defer b.mu.Unlock() - return b.buffer.Write(p) -} - -func (b *bufferWriteCloser) Close() error { - return nil -} - -func (b *bufferWriteCloser) String() string { - b.mu.Lock() - defer b.mu.Unlock() - return b.buffer.String() -} - -// BufferLogger implements LoggerProvider and writes messages in a buffer. -type BufferLogger struct { - WriterLogger -} - -// NewBufferLogger create BufferLogger returning as LoggerProvider. -func NewBufferLogger() LoggerProvider { - log := &BufferLogger{} - log.NewWriterLogger(&bufferWriteCloser{}) - return log -} - -// Init inits connection writer -func (log *BufferLogger) Init(string) error { - log.NewWriterLogger(log.out) - return nil -} - -// Content returns the content accumulated in the content provider -func (log *BufferLogger) Content() (string, error) { - return log.out.(*bufferWriteCloser).String(), nil -} - -// Flush when log should be flushed -func (log *BufferLogger) Flush() { -} - -// ReleaseReopen does nothing -func (log *BufferLogger) ReleaseReopen() error { - return nil -} - -// GetName returns the default name for this implementation -func (log *BufferLogger) GetName() string { - return "buffer" -} - -func init() { - Register("buffer", NewBufferLogger) -} diff --git a/modules/log/buffer_test.go b/modules/log/buffer_test.go deleted file mode 100644 index 1c390060509e3..0000000000000 --- a/modules/log/buffer_test.go +++ /dev/null @@ -1,63 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package log - -import ( - "fmt" - "strings" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -func TestBufferLogger(t *testing.T) { - logger := NewBufferLogger() - bufferLogger := logger.(*BufferLogger) - assert.NotNil(t, bufferLogger) - - err := logger.Init("") - assert.NoError(t, err) - - location, _ := time.LoadLocation("EST") - date := time.Date(2019, time.January, 13, 22, 3, 30, 15, location) - - msg := "TEST MSG" - event := Event{ - level: INFO, - msg: msg, - caller: "CALLER", - filename: "FULL/FILENAME", - line: 1, - time: date, - } - logger.LogEvent(&event) - content, err := bufferLogger.Content() - assert.NoError(t, err) - assert.Contains(t, content, msg) - logger.Close() -} - -func TestBufferLoggerContent(t *testing.T) { - level := INFO - logger := NewLogger(0, "console", "console", fmt.Sprintf(`{"level":"%s"}`, level.String())) - - logger.SetLogger("buffer", "buffer", "{}") - defer logger.DelLogger("buffer") - - msg := "A UNIQUE MESSAGE" - Error(msg) - - found := false - for i := 0; i < 30000; i++ { - content, err := logger.GetLoggerProviderContent("buffer") - assert.NoError(t, err) - if strings.Contains(content, msg) { - found = true - break - } - time.Sleep(1 * time.Millisecond) - } - assert.True(t, found) -} diff --git a/modules/log/conn.go b/modules/log/conn.go index 39d5234214d7f..b21a744037bce 100644 --- a/modules/log/conn.go +++ b/modules/log/conn.go @@ -118,11 +118,6 @@ func (log *ConnLogger) Init(jsonconfig string) error { return nil } -// Content returns the content accumulated in the content provider -func (log *ConnLogger) Content() (string, error) { - return "", fmt.Errorf("not supported") -} - // Flush does nothing for this implementation func (log *ConnLogger) Flush() { } diff --git a/modules/log/console.go b/modules/log/console.go index 8764d984ac109..ce0415d1390c0 100644 --- a/modules/log/console.go +++ b/modules/log/console.go @@ -65,11 +65,6 @@ func (log *ConsoleLogger) Init(config string) error { return nil } -// Content returns the content accumulated in the content provider -func (log *ConsoleLogger) Content() (string, error) { - return "", fmt.Errorf("not supported") -} - // Flush when log should be flushed func (log *ConsoleLogger) Flush() { } diff --git a/modules/log/event.go b/modules/log/event.go index d23e56807b410..5729e022bfe43 100644 --- a/modules/log/event.go +++ b/modules/log/event.go @@ -247,12 +247,6 @@ func (m *MultiChannelledLog) GetEventLogger(name string) EventLogger { return m.loggers[name] } -// GetEventProvider returns a sub logger provider content from this MultiChannelledLog -func (m *MultiChannelledLog) GetLoggerProviderContent(name string) (string, error) { - channelledLogger := m.GetEventLogger(name).(*ChannelledLog) - return channelledLogger.loggerProvider.Content() -} - // GetEventLoggerNames returns a list of names func (m *MultiChannelledLog) GetEventLoggerNames() []string { m.rwmutex.RLock() @@ -460,3 +454,7 @@ func (m *MultiChannelledLog) ResetLevel() Level { func (m *MultiChannelledLog) GetName() string { return m.name } + +func (e *Event) GetMsg() string { + return e.msg +} diff --git a/modules/log/file.go b/modules/log/file.go index 55147ffac8294..2ec6de450c7ea 100644 --- a/modules/log/file.go +++ b/modules/log/file.go @@ -253,15 +253,6 @@ func (log *FileLogger) deleteOldLog() { }) } -// Content returns the content accumulated in the content provider -func (log *FileLogger) Content() (string, error) { - b, err := os.ReadFile(log.Filename) - if err != nil { - return "", err - } - return string(b), nil -} - // Flush flush file logger. // there are no buffering messages in file logger in memory. // flush file means sync file from disk. diff --git a/modules/log/provider.go b/modules/log/provider.go index 490c3fa71b18a..b5058139d7054 100644 --- a/modules/log/provider.go +++ b/modules/log/provider.go @@ -6,7 +6,6 @@ package log // LoggerProvider represents behaviors of a logger provider. type LoggerProvider interface { Init(config string) error - Content() (string, error) EventLogger } diff --git a/modules/log/smtp.go b/modules/log/smtp.go index e385020c67c10..4e896496d75fa 100644 --- a/modules/log/smtp.go +++ b/modules/log/smtp.go @@ -95,11 +95,6 @@ func (log *SMTPLogger) sendMail(p []byte) (int, error) { ) } -// Content returns the content accumulated in the content provider -func (log *SMTPLogger) Content() (string, error) { - return "", fmt.Errorf("not supported") -} - // Flush when log should be flushed func (log *SMTPLogger) Flush() { } diff --git a/modules/test/logchecker.go b/modules/test/logchecker.go new file mode 100644 index 0000000000000..8f8c753c76fcc --- /dev/null +++ b/modules/test/logchecker.go @@ -0,0 +1,116 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package test + +import ( + "strconv" + "strings" + "sync" + "sync/atomic" + "time" + + "code.gitea.io/gitea/modules/log" +) + +type LogChecker struct { + logger *log.MultiChannelledLogger + loggerName string + eventLoggerName string + + filterMessages []string + filtered []bool + + stopMark string + stopped bool + + mu sync.Mutex +} + +func (lc *LogChecker) LogEvent(event *log.Event) error { + lc.mu.Lock() + defer lc.mu.Unlock() + for i, msg := range lc.filterMessages { + if strings.Contains(event.GetMsg(), msg) { + lc.filtered[i] = true + } + } + if strings.Contains(event.GetMsg(), lc.stopMark) { + lc.stopped = true + } + return nil +} + +func (lc *LogChecker) Close() {} + +func (lc *LogChecker) Flush() {} + +func (lc *LogChecker) GetLevel() log.Level { + return log.TRACE +} + +func (lc *LogChecker) GetStacktraceLevel() log.Level { + return log.NONE +} + +func (lc *LogChecker) GetName() string { + return lc.eventLoggerName +} + +func (lc *LogChecker) ReleaseReopen() error { + return nil +} + +var checkerIndex int64 + +func NewLogChecker(loggerName string) (logChecker *LogChecker, cancel func()) { + logger := log.GetLogger(loggerName) + newCheckerIndex := atomic.AddInt64(&checkerIndex, 1) + lc := &LogChecker{ + logger: logger, + loggerName: loggerName, + eventLoggerName: "TestLogChecker-" + strconv.FormatInt(newCheckerIndex, 10), + } + if err := logger.AddLogger(lc); err != nil { + panic(err) // it's impossible + } + return lc, func() { _, _ = logger.DelLogger(lc.GetName()) } +} + +// Filter will make the `Check` function to check if these logs are outputted. +func (lc *LogChecker) Filter(msgs ...string) *LogChecker { + lc.mu.Lock() + defer lc.mu.Unlock() + lc.filterMessages = make([]string, len(msgs)) + copy(lc.filterMessages, msgs) + lc.filtered = make([]bool, len(lc.filterMessages)) + return lc +} + +func (lc *LogChecker) StopMark(msg string) *LogChecker { + lc.mu.Lock() + defer lc.mu.Unlock() + lc.stopMark = msg + lc.stopped = false + return lc +} + +// Check returns the filtered slice and whether the stop mark is reached. +func (lc *LogChecker) Check(d time.Duration) (filtered []bool, stopped bool) { + stop := time.Now().Add(d) + + for { + lc.mu.Lock() + stopped = lc.stopped + lc.mu.Unlock() + + if time.Now().After(stop) || stopped { + lc.mu.Lock() + f := make([]bool, len(lc.filtered)) + copy(f, lc.filtered) + lc.mu.Unlock() + return f, stopped + } + time.Sleep(10 * time.Millisecond) + } +} diff --git a/modules/test/logchecker_test.go b/modules/test/logchecker_test.go new file mode 100644 index 0000000000000..1ed7f427f4bc8 --- /dev/null +++ b/modules/test/logchecker_test.go @@ -0,0 +1,47 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package test + +import ( + "testing" + "time" + + "code.gitea.io/gitea/modules/log" + + "github.com/stretchr/testify/assert" +) + +func TestLogChecker(t *testing.T) { + _ = log.NewLogger(1000, "console", "console", `{"level":"info","stacktracelevel":"NONE","stderr":true}`) + + lc, cleanup := NewLogChecker(log.DEFAULT) + defer cleanup() + + lc.Filter("First", "Third").StopMark("End") + log.Info("test") + + filtered, stopped := lc.Check(100 * time.Millisecond) + assert.EqualValues(t, []bool{false, false}, filtered) + assert.EqualValues(t, false, stopped) + + log.Info("First") + filtered, stopped = lc.Check(100 * time.Millisecond) + assert.EqualValues(t, []bool{true, false}, filtered) + assert.EqualValues(t, false, stopped) + + log.Info("Second") + filtered, stopped = lc.Check(100 * time.Millisecond) + assert.EqualValues(t, []bool{true, false}, filtered) + assert.EqualValues(t, false, stopped) + + log.Info("Third") + filtered, stopped = lc.Check(100 * time.Millisecond) + assert.EqualValues(t, []bool{true, true}, filtered) + assert.EqualValues(t, false, stopped) + + log.Info("End") + filtered, stopped = lc.Check(100 * time.Millisecond) + assert.EqualValues(t, []bool{true, true}, filtered) + assert.EqualValues(t, true, stopped) +} diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index b4b99955c2281..eb63bec93b4cb 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -19,6 +19,7 @@ active_stopwatch=Ενεργή Καταγραφή Χρόνου create_new=Δημιουργία… user_profile_and_more=Προφίλ και ρυθμίσεις… signed_in_as=Είσοδος ως +enable_javascript=Απαιτείται JavaScript για να εμφανιστεί αυτή η ιστοσελίδα. toc=Πίνακας Περιεχομένων licenses=Άδειες return_to_gitea=Επιστροφή στο Gitea @@ -83,6 +84,7 @@ add=Προσθήκη add_all=Προσθήκη Όλων remove=Αφαίρεση remove_all=Αφαίρεση Όλων +remove_label_str=`Αφαίρεση του αντικειμένου "%s"` edit=Επεξεργασία enabled=Ενεργοποιημένο @@ -117,9 +119,26 @@ footer.software=Σχετικά με το Λογισμικό footer.links=Συνδέσεις [heatmap] +number_of_contributions_in_the_last_12_months=%s συνεισφορές τους τελευταίους 12 μήνες +no_contributions=Χωρίς συνεισφορές +less=Λιγότερα +more=Περισσότερα [editor] +buttons.heading.tooltip=Προσθήκη επικεφαλίδας +buttons.bold.tooltip=Προσθήκη έντονου κειμένου +buttons.italic.tooltip=Προσθήκη πλαγίου κειμένου +buttons.quote.tooltip=Παράθεση κειμένου +buttons.code.tooltip=Προσθήκη κώδικα +buttons.link.tooltip=Προσθήκη συνδέσμου buttons.list.unordered.tooltip=Προσθήκη απλής λίστας +buttons.list.ordered.tooltip=Προσθήκη αριθμημένης λίστας +buttons.list.task.tooltip=Προσθήκη λίστας εργασιών +buttons.mention.tooltip=Μνημόνευση ενός χρήστη ή ομάδας +buttons.ref.tooltip=Μνημόνευση ενός θέματος ή pull request +buttons.switch_to_legacy.tooltip=Χρήση του κλασσικού κειμενογράφου +buttons.enable_monospace_font=Ενεργοποίηση σταθερής γραμματοσειράς +buttons.disable_monospace_font=Απενεργοποίηση σταθερής γραμματοσειράς [filter] string.asc=A - Z @@ -222,6 +241,7 @@ openid_signup_popup=Ενεργοποίηση ιδιοεγγραφής χρηστ enable_captcha=Ενεργοποίηση CAPTCHA στην εγγραφή enable_captcha_popup=Απαιτείται ένα CAPTCHA για τη ιδιοεγγραφή του χρήστη. require_sign_in_view=Απαιτείται Είσοδος για τη Προβολή Σελίδων +require_sign_in_view_popup=Περιορισμός της πρόσβασης σε συνδεδεμένους χρήστες. Οι επισκέπτες θα μπορούν μόνο να δουν τις σελίδες εισόδου και εγγραφής. admin_setting_desc=Η δημιουργία ενός λογαριασμού διαχειριστή είναι προαιρετική. Ο πρώτος εγγεγραμμένος χρήστης θα γίνει αυτόματα διαχειριστής. admin_title=Ρυθμίσεις Λογαριασμού Διαχειριστή admin_name=Όνομα Χρήστη Διαχειριστή @@ -232,6 +252,7 @@ install_btn_confirm=Εγκατάσταση Gitea test_git_failed=Αδυναμία δοκιμής της εντολής 'git': %v sqlite3_not_available=Αυτή η έκδοση Gitea δεν υποστηρίζει την SQLite3. Παρακαλώ κατεβάστε την επίσημη δυαδική έκδοση από το %s (όχι την έκδοση 'gobuild'). invalid_db_setting=Οι ρυθμίσεις της βάσης δεδομένων δεν είναι έγκυρες: %v +invalid_db_table=Ο πίνακας βάσης δεδομένων "%s" δεν είναι έγκυρος: %v invalid_repo_path=Η αρχική διαδρομή των αποθετηρίων δεν είναι έγκυρη: %v invalid_app_data_path=Η διαδρομή δεδομένων εφαρμογής (app data) δεν είναι έγκυρη: %v run_user_not_match=Το όνομα χρήστη 'εκτέλεση ως' δεν είναι το τρέχον όνομα χρήστη: %s -> %s @@ -250,6 +271,7 @@ no_reply_address=Κρυφό Όνομα Τομέα Email no_reply_address_helper=Όνομα τομέα για χρήστες με μια κρυφή διεύθυνση email. Για παράδειγμα, το όνομα χρήστη 'nikos' θα συνδεθεί στο Git ως 'nikos@noreply.example.org' αν ο κρυφός τομέας email έχει οριστεί ως 'noreply.example.org'. password_algorithm=Αλγόριθμος Hash Κωδικού Πρόσβασης invalid_password_algorithm=Μη έγκυρος αλγόριθμος κωδικού πρόσβασης +password_algorithm_helper=Ορίστε τον αλγόριθμο κατακερματισμού για το κωδικό πρόσβασης. Οι αλγόριθμοι διαφέρουν σε απαιτήσεις και αντοχή. Ο αλγόριθμος argon2 είναι αρκετά ασφαλής, αλλά χρησιμοποιεί πολλή μνήμη και μπορεί να είναι ακατάλληλος για μικρά συστήματα. enable_update_checker=Ενεργοποίηση Ελεγκτή Ενημερώσεων enable_update_checker_helper=Ελέγχει περιοδικά για νέες εκδόσεις κάνοντας σύνδεση στο gitea.io. @@ -296,6 +318,7 @@ repo_no_results=Δεν βρέθηκαν αποθετήρια που να ται user_no_results=Δεν βρέθηκαν χρήστες που να ταιριάζουν με τα κριτήρια. org_no_results=Δεν βρέθηκαν οργανισμοί που να ταιριάζουν με τα κριτήρια. code_no_results=Δεν βρέθηκε πηγαίος κώδικας που να ταιριάζει με τον όρο αναζήτησης. +code_search_results=`Αποτελέσματα αναζήτησης για "%s"` code_last_indexed_at=Τελευταίο δημιουργία ευρετηρίου στις %s relevant_repositories_tooltip=Τα αποθετήρια που είναι forks ή που δεν έχουν θέμα, εικονίδιο και περιγραφή είναι κρυμμένα. relevant_repositories=Εμφανίζονται μόνο τα σχετικά αποθετήρια, εμφάνιση χωρίς φίλτρο. @@ -472,6 +495,8 @@ size_error=`πρέπει να έχει μέγεθος %s.` min_size_error=` πρέπει να περιέχει τουλάχιστον %s χαρακτήρες.` max_size_error=` πρέπει να περιέχει το πολύ %s χαρακτήρες.` email_error=` δεν είναι έγκυρη διεύθυνση email.` +url_error=`Το "%s" δεν είναι ένα έγκυρο URL.` +include_error=` πρέπει να περιέχει το μέρος "%s".` glob_pattern_error=` το μοτίβο ταιριάσματος (glob) δεν είναι έγκυρο: %s.` regex_pattern_error=` το μοτίβο regex δεν είναι έγκυρο: %s.` username_error=` μπορεί να περιέχει μόνο αλφαριθμητικούς χαρακτήρες ('0-9','a-z','A-Z'), παύλα ('-'), κάτω παύλα ('_') και τελεία ('.'). Δεν μπορεί να ξεκινά ή να τελειώνει με μη αλφαριθμητικούς χαρακτήρες, επίσης απαγορεύονται οι διαδοχικοί μη αλφαριθμητικοί χαρακτήρες.` @@ -496,6 +521,7 @@ team_name_been_taken=Το όνομα της ομάδας χρησιμοποιε team_no_units_error=Να επιτρέπεται η πρόσβαση σε τουλάχιστον μία ενότητα αποθετηρίου. email_been_used=Η διεύθυνση email χρησιμοποιείται ήδη. email_invalid=Η διεύθυνση email δεν είναι έγκυρη. +openid_been_used=Η διεύθυνση OpenID "%s" χρησιμοποιείται ήδη. username_password_incorrect=Το όνομα χρήστη ή ο κωδικός πρόσβασης δεν είναι σωστά. password_complexity=Ο κωδικός πρόσβασης δεν περνά τις απαιτήσεις πολυπλοκότητας: password_lowercase_one=Τουλάχιστον ένα πεζό γράμμα @@ -515,10 +541,16 @@ organization_leave_success=Έχετε εγκαταλείψει με επιτυχ invalid_ssh_key=Δεν είναι δυνατή η επαλήθευση του SSH κλειδιού σας: %s invalid_gpg_key=Δεν είναι δυνατή η επαλήθευση του GPG κλειδιού σας: %s -invalid_ssh_principal=Μη έγκυρος ssh principal: %s +invalid_ssh_principal=Μη έγκυρη αρχή: %s must_use_public_key=Το κλειδί που δώσατε είναι ένα ιδιωτικό κλειδί. Παρακαλώ μην ανεβάζετε το ιδιωτικό σας κλειδί οπουδήποτε. Χρησιμοποιήστε το δημόσιο κλειδί αντί αυτού. +unable_verify_ssh_key=Αδυναμία επαλήθευσης του κλειδιού SSH, ελέγξτε το ξανά για λάθη. auth_failed=Αποτυχία ταυτοποίησης: %v +still_own_repo=Ο λογαριασμός σας κατέχει ένα ή περισσότερα αποθετήρια, διαγράψτε ή μεταφέρετε τα πρώτα. +still_has_org=Ο λογαριασμός σας είναι μέλος σε ένα ή περισσότερους οργανισμούς, φύγετε από αυτούς πρώτα. +still_own_packages=Ο λογαριασμός σας κατέχει ένα ή περισσότερα πακέτα, διαγράψτε τα πρώτα. +org_still_own_repo=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα αποθετήρια, διαγράψτε τα ή μεταφέρετε τα πρώτα. +org_still_own_packages=Αυτός ο οργανισμός κατέχει ακόμα ένα ή περισσότερα πακέτα, διαγράψτε τα πρώτα. target_branch_not_exist=Ο κλάδος προορισμού δεν υπάρχει. @@ -538,7 +570,12 @@ unfollow=Να μην ακολουθώ heatmap.loading=Φόρτωση heatmap… user_bio=Βιογραφικό disabled_public_activity=Αυτός ο χρήστης έχει απενεργοποιήσει τη δημόσια προβολή της δραστηριότητας. +email_visibility.limited=Η διεύθυνση email σας είναι ορατή σε όλους τους ταυτοποιημένους χρήστες +email_visibility.private=Η διεύθυνση email σας είναι ορατή μόνο σε εσάς και στους διαχειριστές +form.name_reserved=Το όνομα χρήστη "%s" είναι δεσμευμένο. +form.name_pattern_not_allowed=Το μοτίβο "%s" δεν επιτρέπεται μέσα σε ένα όνομα χρήστη. +form.name_chars_not_allowed=Το όνομα χρήστη "%s" περιέχει μη έγκυρους χαρακτήρες. [settings] profile=Προφίλ @@ -569,6 +606,7 @@ location=Τοποθεσία update_theme=Ενημέρωση Θέματος Διεπαφής update_profile=Ενημέρωση Προφίλ update_language=Ενημέρωση Γλώσσας +update_language_not_found=Η γλώσσα "%s" δεν είναι διαθέσιμη. update_language_success=Η γλώσσα ενημερώθηκε. update_profile_success=Το προφίλ σας έχει ενημερωθεί. change_username=Το όνομα χρήστη σας έχει αλλάξει. @@ -579,6 +617,9 @@ cancel=Ακύρωση language=Γλώσσα ui=Θέμα Διεπαφής hidden_comment_types=Κρυμμένοι τύποι σχολίων +hidden_comment_types_description=Οι τύποι σχολίων που επιλέγονται εδώ δε θα εμφανίζονται μέσα στις σελίδες ζητημάτων. Επιλέγοντας π.χ το "Σήματα", θα αφαιρεθούν όλα τα σχόλια σαν το " πρόσθεσε/αφαίρεσε τα σήματα