From 3274ab2943ca2cf7e8ac660c9ec505a46385db64 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 21 Apr 2023 21:23:16 +0800 Subject: [PATCH 01/37] Apply to become maintainer (#24254) PRs: https://github.com/go-gitea/gitea/pulls?q=is%3Apr+is%3Aclosed+author%3Awxiaoguang --- MAINTAINERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MAINTAINERS b/MAINTAINERS index f920f71f63e8..ef416639b0fe 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) From 949ba4894b1237490d872277fc48d2a1fdc26562 Mon Sep 17 00:00:00 2001 From: Infinoid Date: Fri, 21 Apr 2023 10:27:32 -0400 Subject: [PATCH 02/37] Fix comment for EmailNotificationsAndYourOwn constant (#24236) This fixes some copypasta in the constant definitions for the `User.EmailNotificationsPreference` field. No code changes. --- models/user/user.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/models/user/user.go b/models/user/user.go index 5f152780bff0..053d6680cdde 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" ) From cb19772d6a2a86d556f350d42758a9d64db1b402 Mon Sep 17 00:00:00 2001 From: harryzcy Date: Fri, 21 Apr 2023 11:39:03 -0400 Subject: [PATCH 03/37] Fix access token issue on some public endpoints (#24194) - [x] Identify endpoints that should be public - [x] Update integration tests Fix #24159 --- routers/api/v1/api.go | 12 ++++++------ tests/integration/api_org_test.go | 22 ++++++++++++++-------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 774eb948ac12..48311b3eee96 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -1200,12 +1200,12 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/{org}/permissions", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetUserOrgsPermissions) }, context_service.UserAssignmentAPI()) m.Post("/orgs", reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateOrgOption{}), org.Create) - m.Get("/orgs", reqToken(auth_model.AccessTokenScopeReadOrg), org.GetAll) + m.Get("/orgs", org.GetAll) m.Group("/orgs/{org}", func() { - m.Combo("").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.Get). + m.Combo("").Get(org.Get). Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditOrgOption{}), org.Edit). Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.Delete) - m.Combo("/repos").Get(reqToken(auth_model.AccessTokenScopeReadOrg), user.ListOrgRepos). + m.Combo("/repos").Get(user.ListOrgRepos). Post(reqToken(auth_model.AccessTokenScopeWriteOrg), bind(api.CreateRepoOption{}), repo.CreateOrgRepo) m.Group("/members", func() { m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListMembers) @@ -1213,8 +1213,8 @@ func Routes(ctx gocontext.Context) *web.Route { Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), org.DeleteMember) }) m.Group("/public_members", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListPublicMembers) - m.Combo("/{username}").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.IsPublicMember). + m.Get("", org.ListPublicMembers) + m.Combo("/{username}").Get(org.IsPublicMember). Put(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.PublicizeMember). Delete(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgMembership(), org.ConcealMember) }) @@ -1224,7 +1224,7 @@ func Routes(ctx gocontext.Context) *web.Route { m.Get("/search", reqToken(auth_model.AccessTokenScopeReadOrg), org.SearchTeam) }, reqOrgMembership()) m.Group("/labels", func() { - m.Get("", reqToken(auth_model.AccessTokenScopeReadOrg), org.ListLabels) + m.Get("", org.ListLabels) m.Post("", reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.CreateLabelOption{}), org.CreateLabel) m.Combo("/{id}").Get(reqToken(auth_model.AccessTokenScopeReadOrg), org.GetLabel). Patch(reqToken(auth_model.AccessTokenScopeWriteOrg), reqOrgOwnership(), bind(api.EditLabelOption{}), org.EditLabel). diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index 3d1c3b2494ca..4b79b32c5948 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -147,16 +147,14 @@ func TestAPIOrgDeny(t *testing.T) { setting.Service.RequireSignInView = false }() - token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrg) - orgName := "user1_org" - req := NewRequestf(t, "GET", "/api/v1/orgs/%s?token=%s", orgName, token) + req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos?token=%s", orgName, token) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/repos", orgName) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members?token=%s", orgName, token) + req = NewRequestf(t, "GET", "/api/v1/orgs/%s/members", orgName) MakeRequest(t, req, http.StatusNotFound) }) } @@ -166,16 +164,24 @@ func TestAPIGetAll(t *testing.T) { token := getUserToken(t, "user1", auth_model.AccessTokenScopeReadOrg) + // accessing with a token will return all orgs req := NewRequestf(t, "GET", "/api/v1/orgs?token=%s", token) resp := MakeRequest(t, req, http.StatusOK) - var apiOrgList []*api.Organization - DecodeJSON(t, resp, &apiOrgList) - // accessing with a token will return all orgs + DecodeJSON(t, resp, &apiOrgList) assert.Len(t, apiOrgList, 9) assert.Equal(t, "org25", apiOrgList[1].FullName) assert.Equal(t, "public", apiOrgList[1].Visibility) + + // accessing without a token will return only public orgs + req = NewRequestf(t, "GET", "/api/v1/orgs") + resp = MakeRequest(t, req, http.StatusOK) + + DecodeJSON(t, resp, &apiOrgList) + assert.Len(t, apiOrgList, 7) + assert.Equal(t, "org25", apiOrgList[0].FullName) + assert.Equal(t, "public", apiOrgList[0].Visibility) } func TestAPIOrgSearchEmptyTeam(t *testing.T) { From 13d1d2764cc1f813f7fc991ba988c1e700fd0f44 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 22 Apr 2023 00:36:37 +0800 Subject: [PATCH 04/37] Show commit history for closed/merged PRs (#24238) Close #24237 Before:
![image](https://user-images.githubusercontent.com/2114189/233424875-a69c6dad-df4a-483e-b796-36c6459af2d6.png)
After: ![image](https://user-images.githubusercontent.com/2114189/233424712-60a296de-017b-49a8-89b2-5925ff452646.png) Co-authored-by: Giteabot --- routers/web/repo/issue.go | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go index a9c67a9e3418..bea35785bbe0 100644 --- a/routers/web/repo/issue.go +++ b/routers/web/repo/issue.go @@ -1621,8 +1621,10 @@ func ViewIssue(ctx *context.Context) { comment.Type == issues_model.CommentTypeStopTracking { // drop error since times could be pruned from DB.. _ = comment.LoadTime() - } else if comment.Type == issues_model.CommentTypeClose { - // record ID of latest closed comment. + } + + if comment.Type == issues_model.CommentTypeClose || comment.Type == issues_model.CommentTypeMergePull { + // record ID of the latest closed/merged comment. // if PR is closed, the comments whose type is CommentTypePullRequestPush(29) after latestCloseCommentID won't be rendered. latestCloseCommentID = comment.ID } From 65fe0fb22cfb264f0b756065d0c3ce7a17d7e55b Mon Sep 17 00:00:00 2001 From: JakobDev Date: Fri, 21 Apr 2023 19:15:49 +0200 Subject: [PATCH 05/37] Allow `webp` images as avatars (#24248) Users can now upload `webp` images. Browsers supporting webp images then display this as the avatar of this user (every major browser except IE). --------- Co-authored-by: silverwind --- assets/go-licenses.json | 5 +++++ go.mod | 3 ++- go.sum | 10 ++++++++-- modules/avatar/avatar.go | 2 ++ 4 files changed, 17 insertions(+), 3 deletions(-) diff --git a/assets/go-licenses.json b/assets/go-licenses.json index 3e7db196f721..1b6ead5df654 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 944f6d2c918c..92201f8e5e40 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 df57c65918b0..a331ec21e7b9 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/modules/avatar/avatar.go b/modules/avatar/avatar.go index 9ee926b059ba..c166f144042a 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 From 911975059a50e71632d33567da7000a97aa28f22 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sat, 22 Apr 2023 04:32:25 +0800 Subject: [PATCH 06/37] Improve test logger (#24235) Before, there was a `log/buffer.go`, but that design is not general, and it introduces a lot of irrelevant `Content() (string, error) ` and `return "", fmt.Errorf("not supported")` . And the old `log/buffer.go` is difficult to use, developers have to write a lot of `Contains` and `Sleep` code. The new `LogChecker` is designed to be a general approach to help to assert some messages appearing or not appearing in logs. --- models/migrations/base/testlogger.go | 5 - modules/log/buffer.go | 71 ------------- modules/log/buffer_test.go | 63 ----------- modules/log/conn.go | 5 - modules/log/console.go | 5 - modules/log/event.go | 10 +- modules/log/file.go | 9 -- modules/log/provider.go | 1 - modules/log/smtp.go | 5 - modules/test/logchecker.go | 116 +++++++++++++++++++++ modules/test/logchecker_test.go | 47 +++++++++ services/migrations/gitea_uploader_test.go | 67 +++++------- tests/testlogger.go | 5 - 13 files changed, 195 insertions(+), 214 deletions(-) delete mode 100644 modules/log/buffer.go delete mode 100644 modules/log/buffer_test.go create mode 100644 modules/test/logchecker.go create mode 100644 modules/test/logchecker_test.go diff --git a/models/migrations/base/testlogger.go b/models/migrations/base/testlogger.go index 7cbf4602be00..80e672952a64 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/modules/log/buffer.go b/modules/log/buffer.go deleted file mode 100644 index 1eee2465f14e..000000000000 --- 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 1c390060509e..000000000000 --- 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 39d5234214d7..b21a744037bc 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 8764d984ac10..ce0415d1390c 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 d23e56807b41..5729e022bfe4 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 55147ffac829..2ec6de450c7e 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 490c3fa71b18..b5058139d705 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 e385020c67c1..4e896496d75f 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 000000000000..8f8c753c76fc --- /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 000000000000..1ed7f427f4bc --- /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/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index 6a942b9b5763..b59ccb7c4415 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -10,7 +10,6 @@ import ( "os" "path/filepath" "strconv" - "strings" "testing" "time" @@ -24,6 +23,7 @@ import ( "code.gitea.io/gitea/modules/log" base "code.gitea.io/gitea/modules/migration" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" @@ -312,10 +312,11 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { })) for _, testCase := range []struct { - name string - head string - assertContent func(t *testing.T, content string) - pr base.PullRequest + name string + head string + logFilter []string + logFiltered []bool + pr base.PullRequest }{ { name: "fork, good Head.SHA", @@ -362,9 +363,8 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { OwnerName: forkRepo.OwnerName, }, }, - assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "Fetch branch from") - }, + logFilter: []string{"Fetch branch from"}, + logFiltered: []bool{true}, }, { name: "invalid fork CloneURL", @@ -388,9 +388,8 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { OwnerName: "WRONG", }, }, - assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "AddRemote") - }, + logFilter: []string{"AddRemote"}, + logFiltered: []bool{true}, }, { name: "no fork, good Head.SHA", @@ -437,10 +436,8 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { OwnerName: fromRepo.OwnerName, }, }, - assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "Empty reference") - assert.NotContains(t, content, "Cannot remove local head") - }, + logFilter: []string{"Empty reference", "Cannot remove local head"}, + logFiltered: []bool{true, false}, }, { name: "no fork, invalid Head.SHA", @@ -464,9 +461,8 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { OwnerName: fromRepo.OwnerName, }, }, - assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "Deprecated local head") - }, + logFilter: []string{"Deprecated local head"}, + logFiltered: []bool{true}, }, { name: "no fork, not found Head.SHA", @@ -490,36 +486,29 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { OwnerName: fromRepo.OwnerName, }, }, - assertContent: func(t *testing.T, content string) { - assert.Contains(t, content, "Deprecated local head") - assert.NotContains(t, content, "Cannot remove local head") - }, + logFilter: []string{"Deprecated local head", "Cannot remove local head"}, + logFiltered: []bool{true, false}, }, } { t.Run(testCase.name, func(t *testing.T) { - logger, ok := log.NamedLoggers.Load(log.DEFAULT) - assert.True(t, ok) - logger.SetLogger("buffer", "buffer", "{}") - defer logger.DelLogger("buffer") + stopMark := fmt.Sprintf(">>>>>>>>>>>>>STOP: %s<<<<<<<<<<<<<<<", testCase.name) + + logChecker, cleanup := test.NewLogChecker(log.DEFAULT) + logChecker.Filter(testCase.logFilter...).StopMark(stopMark) + defer cleanup() testCase.pr.EnsuredSafe = true head, err := uploader.updateGitForPullRequest(&testCase.pr) assert.NoError(t, err) assert.EqualValues(t, testCase.head, head) - if testCase.assertContent != nil { - fence := fmt.Sprintf(">>>>>>>>>>>>>FENCE %s<<<<<<<<<<<<<<<", testCase.name) - log.Error(fence) - var content string - for i := 0; i < 5000; i++ { - content, err = logger.GetLoggerProviderContent("buffer") - assert.NoError(t, err) - if strings.Contains(content, fence) { - break - } - time.Sleep(1 * time.Millisecond) - } - testCase.assertContent(t, content) + + log.Info(stopMark) + + logFiltered, logStopped := logChecker.Check(5 * time.Second) + assert.True(t, logStopped) + if len(testCase.logFilter) > 0 { + assert.EqualValues(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter) } }) } diff --git a/tests/testlogger.go b/tests/testlogger.go index a7cc27a926da..7cac5bbe333b 100644 --- a/tests/testlogger.go +++ b/tests/testlogger.go @@ -180,11 +180,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() { } From 20b6ae0e5399cfc22c6a0989d8e520194e920bdd Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Sat, 22 Apr 2023 06:15:17 +0900 Subject: [PATCH 07/37] Add project type descriptions in issue badge and improve project icons (#23437) Changes: - ~~Add project icons to issue badge~~ ~~After:~~ ![image](https://user-images.githubusercontent.com/18380374/224633165-9d899176-03dc-4c36-94f8-b2fd9583856c.png) Use `tooltip` to add a description of project type to the project name. ![image](https://user-images.githubusercontent.com/18380374/224923685-77201b5a-1c1f-4d37-b867-23299649df3f.png) - improve project icons we can use `project.icon` to get the svg name, which looks better and is easy to change all of them in templates. --------- Co-authored-by: wxiaoguang Co-authored-by: silverwind --- options/locale/locale_en-US.ini | 5 +++++ .../repo/issue/view_content/comments.tmpl | 22 +++++++++++++------ 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index d1ea8f8ed6e3..c0e94d3b8790 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -3414,3 +3414,8 @@ runs.invalid_workflow_helper = Workflow config file is invalid. Please check you runs.no_matching_runner_helper = No matching runner: %s need_approval_desc = Need approval to run workflows for fork pull request. + +[projects] +type-1.display_name = Individual Project +type-2.display_name = Repository Project +type-3.display_name = Organization Project diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl index 116c02b8b5c3..45077e91ba12 100644 --- a/templates/repo/issue/view_content/comments.tmpl +++ b/templates/repo/issue/view_content/comments.tmpl @@ -732,14 +732,22 @@ {{template "shared/user/avatarlink" dict "Context" $.Context "user" .Poster}} {{template "shared/user/authorlink" .Poster}} - {{if gt .OldProjectID 0}} - {{if gt .ProjectID 0}} - {{$.locale.Tr "repo.issues.change_project_at" (.OldProject.Title|Escape) (.Project.Title|Escape) $createdStr | Safe}} - {{else}} - {{$.locale.Tr "repo.issues.remove_project_at" (.OldProject.Title|Escape) $createdStr | Safe}} - {{end}} + {{$oldProjectDisplayHtml := "Unknown Project"}} + {{if .OldProject}} + {{$trKey := printf "projects.type-%d.display_name" .OldProject.Type}} + {{$oldProjectDisplayHtml = printf `%s` ($.locale.Tr $trKey | Escape) (.OldProject.Title | Escape)}} + {{end}} + {{$newProjectDisplayHtml := "Unknown Project"}} + {{if .Project}} + {{$trKey := printf "projects.type-%d.display_name" .Project.Type}} + {{$newProjectDisplayHtml = printf `%s` ($.locale.Tr $trKey | Escape) (.Project.Title | Escape)}} + {{end}} + {{if and (gt .OldProjectID 0) (gt .ProjectID 0)}} + {{$.locale.Tr "repo.issues.change_project_at" $oldProjectDisplayHtml $newProjectDisplayHtml $createdStr | Safe}} + {{else if gt .OldProjectID 0}} + {{$.locale.Tr "repo.issues.remove_project_at" $oldProjectDisplayHtml $createdStr | Safe}} {{else if gt .ProjectID 0}} - {{$.locale.Tr "repo.issues.add_project_at" (.Project.Title|Escape) $createdStr | Safe}} + {{$.locale.Tr "repo.issues.add_project_at" $newProjectDisplayHtml $createdStr | Safe}} {{end}} From 02119ec95e559b1b6d4b48c3b4c8e5ce03e7a299 Mon Sep 17 00:00:00 2001 From: JakobDev Date: Fri, 21 Apr 2023 23:58:59 +0200 Subject: [PATCH 08/37] Limit avatar upload to valid image files (#24258) This causes the browser to allow only valid images in the file picker by default. --------- Co-authored-by: silverwind --- templates/org/settings/options.tmpl | 2 +- templates/repo/settings/options.tmpl | 2 +- templates/user/settings/profile.tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl index 1caa4210e62c..56ad5fa89695 100644 --- a/templates/org/settings/options.tmpl +++ b/templates/org/settings/options.tmpl @@ -91,7 +91,7 @@ {{.CsrfTokenHtml}}
- +
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl index 1aaf58ee91ca..81c1e4759e8d 100644 --- a/templates/repo/settings/options.tmpl +++ b/templates/repo/settings/options.tmpl @@ -60,7 +60,7 @@ {{.CsrfTokenHtml}}
- +
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl index e64f4c7efac5..7ef9a955a7df 100644 --- a/templates/user/settings/profile.tmpl +++ b/templates/user/settings/profile.tmpl @@ -123,7 +123,7 @@
- +
From fb32b4c5340a1b5934e2a5164b0847265167b8b8 Mon Sep 17 00:00:00 2001 From: GiteaBot Date: Sat, 22 Apr 2023 00:07:44 +0000 Subject: [PATCH 09/37] [skip ci] Updated translations via Crowdin --- options/locale/locale_el-GR.ini | 156 +++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 4 deletions(-) diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index b4b99955c228..eb63bec93b4c 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=Οι τύποι σχολίων που επιλέγονται εδώ δε θα εμφανίζονται μέσα στις σελίδες ζητημάτων. Επιλέγοντας π.χ το "Σήματα", θα αφαιρεθούν όλα τα σχόλια σαν το " πρόσθεσε/αφαίρεσε τα σήματα
diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl index 1d55eb39cdc1..137f2c2d9dda 100644 --- a/templates/repo/issue/milestone_issues.tmpl +++ b/templates/repo/issue/milestone_issues.tmpl @@ -65,7 +65,7 @@ {{.locale.Tr "repo.issues.filter_label_exclude" | Safe}} {{.locale.Tr "repo.issues.filter_label_no_select"}} {{range .Labels}} - {{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if contain $.SelLabelIDs .ID}}{{svg "octicon-check"}}{{end}} {{RenderLabel $.Context .}} + {{if .IsExcluded}}{{svg "octicon-circle-slash"}}{{else if SliceUtils.Contains $.SelLabelIDs .ID}}{{svg "octicon-check"}}{{end}} {{RenderLabel $.Context .}} {{end}}
@@ -171,7 +171,7 @@ diff --git a/templates/repo/issue/view_content/attachments.tmpl b/templates/repo/issue/view_content/attachments.tmpl index 7a429c31ecc0..f342340fe474 100644 --- a/templates/repo/issue/view_content/attachments.tmpl +++ b/templates/repo/issue/view_content/attachments.tmpl @@ -8,7 +8,7 @@
{{if FilenameIsImage .Name}} - {{if not (containGeneric $.Content .UUID)}} + {{if not (StringUtils.Contains $.Content .UUID)}} {{$hasThumbnails = true}} {{end}} {{svg "octicon-file"}} @@ -29,7 +29,7 @@
{{- range .Attachments -}} {{if FilenameIsImage .Name}} - {{if not (containGeneric $.Content .UUID)}} + {{if not (StringUtils.Contains $.Content .UUID)}} {{.Name}} diff --git a/templates/repo/settings/tags.tmpl b/templates/repo/settings/tags.tmpl index 0ebaff6fd29f..6387a20de6e6 100644 --- a/templates/repo/settings/tags.tmpl +++ b/templates/repo/settings/tags.tmpl @@ -92,14 +92,14 @@ {{if or .AllowlistUserIDs (and $.Owner.IsOrganization .AllowlistTeamIDs)}} {{$userIDs := .AllowlistUserIDs}} {{range $.Users}} - {{if contain $userIDs .ID}} + {{if SliceUtils.Contains $userIDs .ID}} {{avatar $.Context . 26}} {{.GetDisplayName}} {{end}} {{end}} {{if $.Owner.IsOrganization}} {{$teamIDs := .AllowlistTeamIDs}} {{range $.Teams}} - {{if contain $teamIDs .ID}} + {{if SliceUtils.Contains $teamIDs .ID}} {{.Name}} {{end}} {{end}} From 8dc6eabbc02ef07c76671d53f28baf46871d5b68 Mon Sep 17 00:00:00 2001 From: silverwind Date: Sat, 22 Apr 2023 20:53:00 +0200 Subject: [PATCH 15/37] Update go tool dependencies, restructure lint targets (#24239) - Update all tool dependencies to latest tag - Remove unused errcheck, it is part of golangci-lint - Include main.go in air - Enable wastedassign again now that it's [generics-compatible](https://github.com/golangci/golangci-lint/pull/3689) - Restructured lint targets to new `lint-*` namespace --- .air.toml | 3 +- .drone.yml | 2 +- .golangci.yml | 2 +- Makefile | 110 +++++++++++++-------- modules/charset/escape_stream.go | 4 +- modules/templates/util_dict.go | 2 +- modules/timeutil/since.go | 2 +- modules/translation/i18n/localestore.go | 1 - routers/common/markup.go | 2 +- services/gitdiff/gitdiff_test.go | 11 +-- tests/integration/api_packages_pub_test.go | 2 +- tests/integration/api_repo_test.go | 5 +- 12 files changed, 88 insertions(+), 58 deletions(-) diff --git a/.air.toml b/.air.toml index 069a88924388..fccd89b46c9d 100644 --- a/.air.toml +++ b/.air.toml @@ -5,6 +5,7 @@ tmp_dir = ".air" cmd = "make backend" bin = "gitea" include_ext = ["go", "tmpl"] -exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"] +include_file = ["main.go"] include_dir = ["cmd", "models", "modules", "options", "routers", "services"] +exclude_dir = ["modules/git/tests", "services/gitdiff/testdata", "modules/avatar/testdata", "models/fixtures", "models/migrations/fixtures", "modules/migration/file_format_testdata", "modules/avatar/identicon/testdata"] exclude_regex = ["_test.go$", "_gen.go$"] diff --git a/.drone.yml b/.drone.yml index 789f1ffca415..d1eca955fcc3 100644 --- a/.drone.yml +++ b/.drone.yml @@ -59,7 +59,7 @@ steps: - name: lint-backend-windows image: gitea/test_env:linux-1.20-amd64 # https://gitea.com/gitea/test-env commands: - - make golangci-lint-windows vet + - make lint-go-windows lint-go-vet environment: GOPROXY: https://goproxy.io # proxy.golang.org is blocked in China, this proxy is not GOSUMDB: sum.golang.org diff --git a/.golangci.yml b/.golangci.yml index ebb90af9d504..1be6b63ef3a9 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -22,7 +22,7 @@ linters: - unconvert - unused # - varcheck # deprecated - https://github.com/golangci/golangci-lint/issues/1841 - # - wastedassign # disabled - https://github.com/golangci/golangci-lint/issues/2649 + - wastedassign enable-all: false disable-all: true fast: false diff --git a/Makefile b/Makefile index 59cc27ee8a10..c94f36d6a92f 100644 --- a/Makefile +++ b/Makefile @@ -25,16 +25,15 @@ COMMA := , XGO_VERSION := go-1.20.x -AIR_PACKAGE ?= github.com/cosmtrek/air@v1.40.4 -EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.6.0 -ERRCHECK_PACKAGE ?= github.com/kisielk/errcheck@v1.6.2 -GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.4.0 -GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.51.2 -GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.10 +AIR_PACKAGE ?= github.com/cosmtrek/air@v1.43.0 +EDITORCONFIG_CHECKER_PACKAGE ?= github.com/editorconfig-checker/editorconfig-checker/cmd/editorconfig-checker@2.7.0 +GOFUMPT_PACKAGE ?= mvdan.cc/gofumpt@v0.5.0 +GOLANGCI_LINT_PACKAGE ?= github.com/golangci/golangci-lint/cmd/golangci-lint@v1.52.2 +GXZ_PAGAGE ?= github.com/ulikunitz/xz/cmd/gxz@v0.5.11 MISSPELL_PACKAGE ?= github.com/client9/misspell/cmd/misspell@v0.3.4 SWAGGER_PACKAGE ?= github.com/go-swagger/go-swagger/cmd/swagger@v0.30.4 XGO_PACKAGE ?= src.techknowlogick.com/xgo@latest -GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.5.0 +GO_LICENSES_PACKAGE ?= github.com/google/go-licenses@v1.6.0 GOVULNCHECK_PACKAGE ?= golang.org/x/vuln/cmd/govulncheck@latest DOCKER_IMAGE ?= gitea/gitea @@ -194,9 +193,20 @@ help: @echo " - deps-backend install backend dependencies" @echo " - deps-tools install tool dependencies" @echo " - lint lint everything" + @echo " - lint-fix lint everything and fix issues" @echo " - lint-frontend lint frontend files" + @echo " - lint-frontend-fix lint frontend files and fix issues" @echo " - lint-backend lint backend files" + @echo " - lint-backend-fix lint backend files and fix issues" + @echo " - lint-go lint go files" + @echo " - lint-go-fix lint go files and fix issues" + @echo " - lint-go-vet lint go files with vet" + @echo " - lint-js lint js files" + @echo " - lint-js-fix lint js files and fix issues" + @echo " - lint-css lint css files" + @echo " - lint-css-fix lint css files and fix issues" @echo " - lint-md lint markdown files" + @echo " - lint-swagger lint swagger files" @echo " - checks run various consistency checks" @echo " - checks-frontend check frontend files" @echo " - checks-backend check backend files" @@ -214,9 +224,7 @@ help: @echo " - generate-manpage generate manpage" @echo " - generate-swagger generate the swagger spec from code comments" @echo " - swagger-validate check if the swagger spec is valid" - @echo " - golangci-lint run golangci-lint linter" @echo " - go-licenses regenerate go licenses" - @echo " - vet examines Go source code and reports suspicious constructs" @echo " - tidy run go mod tidy" @echo " - test[\#TestSpecificName] run unit test" @echo " - test-sqlite[\#TestSpecificName] run integration test for sqlite" @@ -286,12 +294,6 @@ fmt-check: fmt misspell-check: go run $(MISSPELL_PACKAGE) -error $(GO_DIRS) $(WEB_DIRS) -.PHONY: vet -vet: - @echo "Running go vet..." - @GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet - @$(GO) vet -vettool=gitea-vet $(GO_PACKAGES) - .PHONY: $(TAGS_EVIDENCE) $(TAGS_EVIDENCE): @mkdir -p $(MAKE_EVIDENCE_DIR) @@ -324,11 +326,6 @@ swagger-validate: $(GO) run $(SWAGGER_PACKAGE) validate './$(SWAGGER_SPEC)' $(SED_INPLACE) '$(SWAGGER_SPEC_S_TMPL)' './$(SWAGGER_SPEC)' -.PHONY: errcheck -errcheck: - @echo "Running errcheck..." - $(GO) run $(ERRCHECK_PACKAGE) $(GO_PACKAGES) - .PHONY: checks checks: checks-frontend checks-backend @@ -341,18 +338,69 @@ checks-backend: tidy-check swagger-check fmt-check misspell-check swagger-valida .PHONY: lint lint: lint-frontend lint-backend +.PHONY: lint-fix +lint-fix: lint-frontend-fix lint-backend-fix + .PHONY: lint-frontend -lint-frontend: node_modules lint-md +lint-frontend: lint-js lint-css lint-md lint-swagger + +.PHONY: lint-frontend-fix +lint-frontend-fix: lint-js-fix lint-css-fix lint-md lint-swagger + +.PHONY: lint-backend +lint-backend: lint-go lint-go-vet lint-editorconfig + +.PHONY: lint-backend-fix +lint-backend-fix: lint-go-fix lint-go-vet lint-editorconfig + +.PHONY: lint-js +lint-js: node_modules npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e + +.PHONY: lint-js-fix +lint-js-fix: node_modules + npx eslint --color --max-warnings=0 --ext js,vue web_src/js build *.config.js docs/assets/js tests/e2e --fix + +.PHONY: lint-css +lint-css: node_modules npx stylelint --color --max-warnings=0 web_src/css + +.PHONY: lint-css-fix +lint-css-fix: node_modules + npx stylelint --color --max-warnings=0 web_src/css --fix + +.PHONY: lint-swagger +lint-swagger: node_modules npx spectral lint -q -F hint $(SWAGGER_SPEC) .PHONY: lint-md lint-md: node_modules npx markdownlint docs *.md -.PHONY: lint-backend -lint-backend: golangci-lint vet editorconfig-checker +.PHONY: lint-go +lint-go: + $(GO) run $(GOLANGCI_LINT_PACKAGE) run + +.PHONY: lint-go-fix +lint-go-fix: + $(GO) run $(GOLANGCI_LINT_PACKAGE) run --fix + +# workaround step for the lint-backend-windows CI task because 'go run' can not +# have distinct GOOS/GOARCH for its build and run steps +.PHONY: lint-go-windows +lint-go-windows: + @GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE) + golangci-lint run + +.PHONY: lint-go-vet +lint-go-vet: + @echo "Running go vet..." + @GOOS= GOARCH= $(GO) build code.gitea.io/gitea-vet + @$(GO) vet -vettool=gitea-vet $(GO_PACKAGES) + +.PHONY: lint-editorconfig +lint-editorconfig: + $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates .PHONY: watch watch: @@ -843,7 +891,6 @@ deps-backend: deps-tools: $(GO) install $(AIR_PACKAGE) $(GO) install $(EDITORCONFIG_CHECKER_PACKAGE) - $(GO) install $(ERRCHECK_PACKAGE) $(GO) install $(GOFUMPT_PACKAGE) $(GO) install $(GOLANGCI_LINT_PACKAGE) $(GO) install $(GXZ_PAGAGE) @@ -942,21 +989,6 @@ generate-manpage: @gzip -9 man/man1/gitea.1 && echo man/man1/gitea.1.gz created @#TODO A small script that formats config-cheat-sheet.en-us.md nicely for use as a config man page -.PHONY: golangci-lint -golangci-lint: - $(GO) run $(GOLANGCI_LINT_PACKAGE) run - -# workaround step for the lint-backend-windows CI task because 'go run' can not -# have distinct GOOS/GOARCH for its build and run steps -.PHONY: golangci-lint-windows -golangci-lint-windows: - @GOOS= GOARCH= $(GO) install $(GOLANGCI_LINT_PACKAGE) - golangci-lint run - -.PHONY: editorconfig-checker -editorconfig-checker: - $(GO) run $(EDITORCONFIG_CHECKER_PACKAGE) templates - .PHONY: docker docker: docker build --disable-content-trust=false -t $(DOCKER_REF) . diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go index 89bf36edce1a..03d4cfc0c17b 100644 --- a/modules/charset/escape_stream.go +++ b/modules/charset/escape_stream.go @@ -47,7 +47,9 @@ func (e *escapeStreamer) EscapeStatus() *EscapeStatus { // Text tells the next streamer there is a text func (e *escapeStreamer) Text(data string) error { sb := &strings.Builder{} - pos, until, next := 0, 0, 0 + var until int + var next int + pos := 0 if len(data) > len(UTF8BOM) && data[:len(UTF8BOM)] == string(UTF8BOM) { _, _ = sb.WriteString(data[:len(UTF8BOM)]) pos = len(UTF8BOM) diff --git a/modules/templates/util_dict.go b/modules/templates/util_dict.go index c83f22449cdc..79c307b68d9a 100644 --- a/modules/templates/util_dict.go +++ b/modules/templates/util_dict.go @@ -108,7 +108,7 @@ func dumpVar(v any) template.HTML { return "
dumpVar: only available in dev mode
" } m, ok := dumpVarMarshalable(v, map[uintptr]bool{}) - dumpStr := "" + var dumpStr string jsonBytes, err := json.MarshalIndent(m, "", " ") if err != nil { dumpStr = fmt.Sprintf("dumpVar: unable to marshal %T: %v", v, err) diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go index e6a2519d2120..4aee814ecdc6 100644 --- a/modules/timeutil/since.go +++ b/modules/timeutil/since.go @@ -23,7 +23,7 @@ const ( ) func computeTimeDiffFloor(diff int64, lang translation.Locale) (int64, string) { - diffStr := "" + var diffStr string switch { case diff <= 0: diff = 0 diff --git a/modules/translation/i18n/localestore.go b/modules/translation/i18n/localestore.go index 90f574127d11..0664bcfd1a22 100644 --- a/modules/translation/i18n/localestore.go +++ b/modules/translation/i18n/localestore.go @@ -72,7 +72,6 @@ func (store *localeStore) AddLocaleByIni(langName, langDesc string, source, more l.idxToMsgMap[idx] = key.Value() } } - iniFile = nil return nil } diff --git a/routers/common/markup.go b/routers/common/markup.go index 89f24e00075c..3acd12721e85 100644 --- a/routers/common/markup.go +++ b/routers/common/markup.go @@ -20,7 +20,7 @@ import ( // RenderMarkup renders markup text for the /markup and /markdown endpoints func RenderMarkup(ctx *context.Context, mode, text, urlPrefix, filePath string, wiki bool) { - markupType := "" + var markupType string relativePath := "" if len(text) == 0 { diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go index eb9ed862e82f..389f787dfc44 100644 --- a/services/gitdiff/gitdiff_test.go +++ b/services/gitdiff/gitdiff_test.go @@ -520,7 +520,7 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") + _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } @@ -536,11 +536,10 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2), "") + _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } - println(result) diff2a := `diff --git "a/A \\ B" b/A/B --- "a/A \\ B" @@ -553,11 +552,10 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a), "") + _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff2a), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } - println(result) diff3 := `diff --git a/README.md b/README.md --- a/README.md @@ -570,11 +568,10 @@ index 0000000..6bb8f39 Docker Pulls + cut off + cut off` - result, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3), "") + _, err = ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, strings.NewReader(diff3), "") if err != nil { t.Errorf("ParsePatch failed: %s", err) } - println(result) } func setupDefaultDiff() *Diff { diff --git a/tests/integration/api_packages_pub_test.go b/tests/integration/api_packages_pub_test.go index 24975ab6210a..4d4ce1240272 100644 --- a/tests/integration/api_packages_pub_test.go +++ b/tests/integration/api_packages_pub_test.go @@ -120,7 +120,7 @@ description: ` + packageDescription assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - resp = uploadFile(t, result.URL, content, http.StatusBadRequest) + _ = uploadFile(t, result.URL, content, http.StatusBadRequest) }) t.Run("Download", func(t *testing.T) { diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index b3a184edddae..ecaa9fe9866b 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -183,18 +183,17 @@ func TestAPISearchRepo(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { for userToLogin, expected := range testCase.expectedResults { - var session *TestSession var testName string var userID int64 var token string if userToLogin != nil && userToLogin.ID > 0 { testName = fmt.Sprintf("LoggedUser%d", userToLogin.ID) - session = loginUser(t, userToLogin.Name) + session := loginUser(t, userToLogin.Name) token = getTokenForLoggedInUser(t, session) userID = userToLogin.ID } else { testName = "AnonymousUser" - session = emptyTestSession(t) + _ = emptyTestSession(t) } t.Run(testName, func(t *testing.T) { From ac384c4e1d207a989d0f646ebc14fd0c26427d4c Mon Sep 17 00:00:00 2001 From: Jason Song Date: Sun, 23 Apr 2023 04:12:41 +0800 Subject: [PATCH 16/37] Support upload `outputs` and use `needs` context on Actions (#24230) See [Defining outputs for jobs](https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs) and [Example usage of the needs context](https://docs.github.com/en/actions/learn-github-actions/contexts#example-usage-of-the-needs-context). Related to: - [actions-proto-def #5](https://gitea.com/gitea/actions-proto-def/pulls/5) - [act_runner #133](https://gitea.com/gitea/act_runner/pulls/133)
Tests & screenshots Test workflow file: ```yaml name: outputs on: push jobs: job1: runs-on: ubuntu-latest outputs: output1: ${{ steps.step1.outputs.output1 }} output2: ${{ steps.step2.outputs.output2 }} steps: - name: step1 id: step1 run: | date -Is > output1 cat output1 echo "output1=$(cat output1)" >> $GITHUB_OUTPUT - name: step2 id: step2 run: | cat /proc/sys/kernel/random/uuid > output2 cat output2 echo "output2=$(cat output2)" >> $GITHUB_OUTPUT job2: needs: job1 runs-on: ubuntu-latest steps: - run: echo ${{ needs.job1.outputs.output1 }} - run: echo ${{ needs.job1.outputs.output2 }} - run: echo ${{ needs.job1.result }} ``` image image
--------- Co-authored-by: Giteabot --- go.mod | 2 +- go.sum | 4 +-- models/actions/task_output.go | 51 ++++++++++++++++++++++++++ models/migrations/migrations.go | 2 ++ models/migrations/v1_20/v254.go | 18 ++++++++++ routers/api/actions/runner/runner.go | 28 ++++++++++++++- routers/api/actions/runner/utils.go | 54 ++++++++++++++++++++++++++++ 7 files changed, 155 insertions(+), 4 deletions(-) create mode 100644 models/actions/task_output.go create mode 100644 models/migrations/v1_20/v254.go diff --git a/go.mod b/go.mod index 92201f8e5e40..9f0a23f4550f 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module code.gitea.io/gitea go 1.19 require ( - code.gitea.io/actions-proto-go v0.2.0 + code.gitea.io/actions-proto-go v0.2.1 code.gitea.io/gitea-vet v0.2.2 code.gitea.io/sdk/gitea v0.15.1 codeberg.org/gusted/mcaptcha v0.0.0-20220723083913-4f3072e1d570 diff --git a/go.sum b/go.sum index a331ec21e7b9..e48fa8b45b80 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo= -code.gitea.io/actions-proto-go v0.2.0 h1:nYh9nhhfk67YA4wVNLsCzd//RCvXnljwXClJ33+HPVk= -code.gitea.io/actions-proto-go v0.2.0/go.mod h1:00ys5QDo1iHN1tHNvvddAcy2W/g+425hQya1cCSvq9A= +code.gitea.io/actions-proto-go v0.2.1 h1:ToMN/8thz2q10TuCq8dL2d8mI+/pWpJcHCvG+TELwa0= +code.gitea.io/actions-proto-go v0.2.1/go.mod h1:00ys5QDo1iHN1tHNvvddAcy2W/g+425hQya1cCSvq9A= code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= code.gitea.io/gitea-vet v0.2.2 h1:TEOV/Glf38iGmKzKP0EB++Z5OSL4zGg3RrAvlwaMuvk= code.gitea.io/gitea-vet v0.2.2/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE= diff --git a/models/actions/task_output.go b/models/actions/task_output.go new file mode 100644 index 000000000000..5291a783d669 --- /dev/null +++ b/models/actions/task_output.go @@ -0,0 +1,51 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package actions + +import ( + "context" + + "code.gitea.io/gitea/models/db" +) + +// ActionTaskOutput represents an output of ActionTask. +// So the outputs are bound to a task, that means when a completed job has been rerun, +// the outputs of the job will be reset because the task is new. +// It's by design, to avoid the outputs of the old task to be mixed with the new task. +type ActionTaskOutput struct { + ID int64 + TaskID int64 `xorm:"INDEX UNIQUE(task_id_output_key)"` + OutputKey string `xorm:"VARCHAR(255) UNIQUE(task_id_output_key)"` + OutputValue string `xorm:"MEDIUMTEXT"` +} + +// FindTaskOutputByTaskID returns the outputs of the task. +func FindTaskOutputByTaskID(ctx context.Context, taskID int64) ([]*ActionTaskOutput, error) { + var outputs []*ActionTaskOutput + return outputs, db.GetEngine(ctx).Where("task_id=?", taskID).Find(&outputs) +} + +// FindTaskOutputKeyByTaskID returns the keys of the outputs of the task. +func FindTaskOutputKeyByTaskID(ctx context.Context, taskID int64) ([]string, error) { + var keys []string + return keys, db.GetEngine(ctx).Table(ActionTaskOutput{}).Where("task_id=?", taskID).Cols("output_key").Find(&keys) +} + +// InsertTaskOutputIfNotExist inserts a new task output if it does not exist. +func InsertTaskOutputIfNotExist(ctx context.Context, taskID int64, key, value string) error { + return db.WithTx(ctx, func(ctx context.Context) error { + sess := db.GetEngine(ctx) + if exist, err := sess.Exist(&ActionTaskOutput{TaskID: taskID, OutputKey: key}); err != nil { + return err + } else if exist { + return nil + } + _, err := sess.Insert(&ActionTaskOutput{ + TaskID: taskID, + OutputKey: key, + OutputValue: value, + }) + return err + }) +} diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 42806a808f79..9de5931d7146 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -485,6 +485,8 @@ var migrations = []Migration{ NewMigration("Fix incorrect admin team unit access mode", v1_20.FixIncorrectAdminTeamUnitAccessMode), // v253 -> v254 NewMigration("Fix ExternalTracker and ExternalWiki accessMode in owner and admin team", v1_20.FixExternalTrackerAndExternalWikiAccessModeInOwnerAndAdminTeam), + // v254 -> v255 + NewMigration("Add ActionTaskOutput table", v1_20.AddActionTaskOutputTable), } // GetCurrentDBVersion returns the current db version diff --git a/models/migrations/v1_20/v254.go b/models/migrations/v1_20/v254.go new file mode 100644 index 000000000000..1e26979a5b2a --- /dev/null +++ b/models/migrations/v1_20/v254.go @@ -0,0 +1,18 @@ +// Copyright 2023 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_20 //nolint + +import ( + "xorm.io/xorm" +) + +func AddActionTaskOutputTable(x *xorm.Engine) error { + type ActionTaskOutput struct { + ID int64 + TaskID int64 `xorm:"INDEX UNIQUE(task_id_output_key)"` + OutputKey string `xorm:"VARCHAR(255) UNIQUE(task_id_output_key)"` + OutputValue string `xorm:"MEDIUMTEXT"` + } + return x.Sync(new(ActionTaskOutput)) +} diff --git a/routers/api/actions/runner/runner.go b/routers/api/actions/runner/runner.go index a44586485893..73c6b746a0fe 100644 --- a/routers/api/actions/runner/runner.go +++ b/routers/api/actions/runner/runner.go @@ -97,7 +97,7 @@ func (s *Service) Register( // FetchTask assigns a task to the runner func (s *Service) FetchTask( ctx context.Context, - req *connect.Request[runnerv1.FetchTaskRequest], + _ *connect.Request[runnerv1.FetchTaskRequest], ) (*connect.Response[runnerv1.FetchTaskResponse], error) { runner := GetRunner(ctx) @@ -145,6 +145,31 @@ func (s *Service) UpdateTask( return nil, status.Errorf(codes.Internal, "update task: %v", err) } + for k, v := range req.Msg.Outputs { + if len(k) > 255 { + log.Warn("Ignore the output of task %d because the key is too long: %q", task.ID, k) + continue + } + // The value can be a maximum of 1 MB + if l := len(v); l > 1024*1024 { + log.Warn("Ignore the output %q of task %d because the value is too long: %v", k, task.ID, l) + continue + } + // There's another limitation on GitHub that the total of all outputs in a workflow run can be a maximum of 50 MB. + // We don't check the total size here because it's not easy to do, and it doesn't really worth it. + // See https://docs.github.com/en/actions/using-jobs/defining-outputs-for-jobs + + if err := actions_model.InsertTaskOutputIfNotExist(ctx, task.ID, k, v); err != nil { + log.Warn("Failed to insert the output %q of task %d: %v", k, task.ID, err) + // It's ok not to return errors, the runner will resend the outputs. + } + } + sentOutputs, err := actions_model.FindTaskOutputKeyByTaskID(ctx, task.ID) + if err != nil { + log.Warn("Failed to find the sent outputs of task %d: %v", task.ID, err) + // It's not to return errors, it can be handled when the runner resends sent outputs. + } + if err := task.LoadJob(ctx); err != nil { return nil, status.Errorf(codes.Internal, "load job: %v", err) } @@ -162,6 +187,7 @@ func (s *Service) UpdateTask( Id: req.Msg.State.Id, Result: task.Status.AsResult(), }, + SentOutputs: sentOutputs, }), nil } diff --git a/routers/api/actions/runner/utils.go b/routers/api/actions/runner/utils.go index cbfcd79a9d99..705867a9b106 100644 --- a/routers/api/actions/runner/utils.go +++ b/routers/api/actions/runner/utils.go @@ -37,6 +37,17 @@ func pickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv Context: generateTaskContext(t), Secrets: getSecretsOfTask(ctx, t), } + + if needs, err := findTaskNeeds(ctx, t); err != nil { + log.Error("Cannot find needs for task %v: %v", t.ID, err) + // Go on with empty needs. + // If return error, the task will be wild, which means the runner will never get it when it has been assigned to the runner. + // In contrast, missing needs is less serious. + // And the task will fail and the runner will report the error in the logs. + } else { + task.Needs = needs + } + return task, true, nil } @@ -124,3 +135,46 @@ func generateTaskContext(t *actions_model.ActionTask) *structpb.Struct { return taskContext } + +func findTaskNeeds(ctx context.Context, task *actions_model.ActionTask) (map[string]*runnerv1.TaskNeed, error) { + if err := task.LoadAttributes(ctx); err != nil { + return nil, fmt.Errorf("LoadAttributes: %w", err) + } + if len(task.Job.Needs) == 0 { + return nil, nil + } + needs := map[string]struct{}{} + for _, v := range task.Job.Needs { + needs[v] = struct{}{} + } + + jobs, _, err := actions_model.FindRunJobs(ctx, actions_model.FindRunJobOptions{RunID: task.Job.RunID}) + if err != nil { + return nil, fmt.Errorf("FindRunJobs: %w", err) + } + + ret := make(map[string]*runnerv1.TaskNeed, len(needs)) + for _, job := range jobs { + if _, ok := needs[job.JobID]; !ok { + continue + } + if job.TaskID == 0 || !job.Status.IsDone() { + // it shouldn't happen, or the job has been rerun + continue + } + outputs := make(map[string]string) + got, err := actions_model.FindTaskOutputByTaskID(ctx, job.TaskID) + if err != nil { + return nil, fmt.Errorf("FindTaskOutputByTaskID: %w", err) + } + for _, v := range got { + outputs[v.OutputKey] = v.OutputValue + } + ret[job.JobID] = &runnerv1.TaskNeed{ + Outputs: outputs, + Result: runnerv1.Result(job.Status), + } + } + + return ret, nil +} From f1173d6879cb26af21483037fae72542f3088408 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Sat, 22 Apr 2023 23:56:27 +0200 Subject: [PATCH 17/37] Use more specific test methods (#24265) Co-authored-by: silverwind Co-authored-by: Giteabot --- cmd/migrate_storage_test.go | 2 +- models/db/list_test.go | 2 +- models/git/branches_test.go | 6 +-- models/issues/pull_test.go | 4 +- models/issues/tracked_time_test.go | 2 +- models/unittest/consistency.go | 2 +- models/user/user_test.go | 6 +-- modules/git/repo_attribute_test.go | 4 +- modules/git/repo_commit_test.go | 2 +- modules/git/repo_tag_test.go | 2 +- modules/indexer/code/indexer_test.go | 2 +- modules/lfs/http_client_test.go | 4 +- modules/log/file_test.go | 2 +- modules/markup/html_test.go | 2 +- modules/packages/container/metadata_test.go | 2 +- modules/paginator/paginator_test.go | 40 +++++++++---------- .../queue/unique_queue_disk_channel_test.go | 2 +- modules/secret/secret_test.go | 4 +- modules/storage/local_test.go | 2 +- modules/test/logchecker_test.go | 20 +++++----- modules/translation/i18n/i18n_test.go | 4 +- modules/util/slice_test.go | 22 +++++----- modules/util/truncate_test.go | 2 +- services/issue/assignee_test.go | 6 +-- services/issue/issue_test.go | 6 +-- services/repository/adopt_test.go | 6 +-- tests/integration/api_admin_test.go | 2 +- .../api_comment_attachment_test.go | 2 +- tests/integration/api_comment_test.go | 4 +- tests/integration/api_issue_config_test.go | 2 +- tests/integration/api_pull_review_test.go | 6 +-- tests/integration/api_pull_test.go | 6 +-- tests/integration/api_repo_archive_test.go | 6 +-- tests/integration/api_repo_edit_test.go | 14 +++---- tests/integration/api_repo_test.go | 4 +- tests/integration/auth_ldap_test.go | 8 ++-- tests/integration/cors_test.go | 2 +- tests/integration/empty_repo_test.go | 4 +- tests/integration/git_test.go | 8 ++-- tests/integration/pull_merge_test.go | 2 +- tests/integration/repo_test.go | 8 ++-- 41 files changed, 118 insertions(+), 118 deletions(-) diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go index aae366c0cf52..e6658b6e65ef 100644 --- a/cmd/migrate_storage_test.go +++ b/cmd/migrate_storage_test.go @@ -67,7 +67,7 @@ func TestMigratePackages(t *testing.T) { entries, err := os.ReadDir(p) assert.NoError(t, err) - assert.EqualValues(t, 2, len(entries)) + assert.Len(t, entries, 2) assert.EqualValues(t, "01", entries[0].Name()) assert.EqualValues(t, "tmp", entries[1].Name()) } diff --git a/models/db/list_test.go b/models/db/list_test.go index 6b9bebd64bd4..b923dc9c22da 100644 --- a/models/db/list_test.go +++ b/models/db/list_test.go @@ -40,7 +40,7 @@ func TestFind(t *testing.T) { var repoUnits []repo_model.RepoUnit err = db.Find(db.DefaultContext, &opts, &repoUnits) assert.NoError(t, err) - assert.EqualValues(t, repoUnitCount, len(repoUnits)) + assert.Len(t, repoUnits, repoUnitCount) cnt, err := db.Count(db.DefaultContext, &opts, new(repo_model.RepoUnit)) assert.NoError(t, err) diff --git a/models/git/branches_test.go b/models/git/branches_test.go index b7df7f243e33..5d18d9525ef8 100644 --- a/models/git/branches_test.go +++ b/models/git/branches_test.go @@ -88,12 +88,12 @@ func TestFindRenamedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) branch, exist, err := git_model.FindRenamedBranch(db.DefaultContext, 1, "dev") assert.NoError(t, err) - assert.Equal(t, true, exist) + assert.True(t, exist) assert.Equal(t, "master", branch.To) _, exist, err = git_model.FindRenamedBranch(db.DefaultContext, 1, "unknow") assert.NoError(t, err) - assert.Equal(t, false, exist) + assert.False(t, exist) } func TestRenameBranch(t *testing.T) { @@ -115,7 +115,7 @@ func TestRenameBranch(t *testing.T) { return nil })) - assert.Equal(t, true, _isDefault) + assert.True(t, _isDefault) repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) assert.Equal(t, "main", repo1.DefaultBranch) diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index bcd33329eb9b..8d99b2667ca6 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -109,11 +109,11 @@ func TestHasUnmergedPullRequestsByHeadInfo(t *testing.T) { exist, err := issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "branch2") assert.NoError(t, err) - assert.Equal(t, true, exist) + assert.True(t, exist) exist, err = issues_model.HasUnmergedPullRequestsByHeadInfo(db.DefaultContext, 1, "not_exist_branch") assert.NoError(t, err) - assert.Equal(t, false, exist) + assert.False(t, exist) } func TestGetUnmergedPullRequestsByHeadInfo(t *testing.T) { diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go index becfd79d41b0..99b977cca526 100644 --- a/models/issues/tracked_time_test.go +++ b/models/issues/tracked_time_test.go @@ -35,7 +35,7 @@ func TestAddTime(t *testing.T) { assert.Equal(t, int64(3661), tt.Time) comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}) - assert.Equal(t, comment.Content, "1 hour 1 minute") + assert.Equal(t, "1 hour 1 minute", comment.Content) } func TestGetTrackedTimes(t *testing.T) { diff --git a/models/unittest/consistency.go b/models/unittest/consistency.go index 17ff75c089f1..41798c62536f 100644 --- a/models/unittest/consistency.go +++ b/models/unittest/consistency.go @@ -152,7 +152,7 @@ func init() { Query() assert.NoError(t, err) - assert.EqualValues(t, label.int("NumIssues"), len(issueLabels), "Unexpected number of issue for label id: %d", label.int("ID")) + assert.Len(t, issueLabels, label.int("NumIssues"), "Unexpected number of issue for label id: %d", label.int("ID")) issueIDs := make([]int, len(issueLabels)) for i, issueLabel := range issueLabels { diff --git a/models/user/user_test.go b/models/user/user_test.go index c2314d5c0388..cbfcd15463a8 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -36,10 +36,10 @@ func TestGetUserEmailsByNames(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // ignore none active user email - assert.Equal(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"})) - assert.Equal(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"})) + assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"})) + assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"})) - assert.Equal(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user7"})) + assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user7"})) } func TestCanCreateOrganization(t *testing.T) { diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go index f88ae9540786..350b69dd251b 100644 --- a/modules/git/repo_attribute_test.go +++ b/modules/git/repo_attribute_test.go @@ -19,7 +19,7 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { n, err := wr.Write([]byte(testStr)) - assert.Equal(t, n, len(testStr)) + assert.Len(t, testStr, n) assert.NoError(t, err) select { case attr := <-wr.ReadAttribute(): @@ -32,7 +32,7 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { // Write a second attribute again n, err = wr.Write([]byte(testStr)) - assert.Equal(t, n, len(testStr)) + assert.Len(t, testStr, n) assert.NoError(t, err) select { diff --git a/modules/git/repo_commit_test.go b/modules/git/repo_commit_test.go index 729fb0ba103a..fee145e924e9 100644 --- a/modules/git/repo_commit_test.go +++ b/modules/git/repo_commit_test.go @@ -97,6 +97,6 @@ func TestRepository_CommitsBetweenIDs(t *testing.T) { for i, c := range cases { commits, err := bareRepo1.CommitsBetweenIDs(c.NewID, c.OldID) assert.NoError(t, err) - assert.Equal(t, c.ExpectedCommits, len(commits), "case %d", i) + assert.Len(t, commits, c.ExpectedCommits, "case %d", i) } } diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index 8ccfec3eb23e..fb6a7cdd1add 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -26,7 +26,7 @@ func TestRepository_GetTags(t *testing.T) { return } assert.Len(t, tags, 2) - assert.Equal(t, len(tags), total) + assert.Len(t, tags, total) assert.EqualValues(t, "signed-tag", tags[0].Name) assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String()) assert.EqualValues(t, "tag", tags[0].Type) diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go index c353d5b6880f..52f7e76e413f 100644 --- a/modules/indexer/code/indexer_test.go +++ b/modules/indexer/code/indexer_test.go @@ -69,7 +69,7 @@ func testIndexer(name string, t *testing.T, indexer Indexer) { t.Run(kw.Keyword, func(t *testing.T) { total, res, langs, err := indexer.Search(context.TODO(), kw.RepoIDs, "", kw.Keyword, 1, 10, false) assert.NoError(t, err) - assert.EqualValues(t, len(kw.IDs), total) + assert.Len(t, kw.IDs, int(total)) assert.Len(t, langs, kw.Langs) ids := make([]int64, 0, len(res)) diff --git a/modules/lfs/http_client_test.go b/modules/lfs/http_client_test.go index a8c7e379f66f..cb71b9008a9d 100644 --- a/modules/lfs/http_client_test.go +++ b/modules/lfs/http_client_test.go @@ -162,7 +162,7 @@ func TestHTTPClientDownload(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "download", batchRequest.Operation) - assert.Equal(t, 1, len(batchRequest.Objects)) + assert.Len(t, batchRequest.Objects, 1) assert.Equal(t, p.Oid, batchRequest.Objects[0].Oid) assert.Equal(t, p.Size, batchRequest.Objects[0].Size) @@ -269,7 +269,7 @@ func TestHTTPClientUpload(t *testing.T) { assert.NoError(t, err) assert.Equal(t, "upload", batchRequest.Operation) - assert.Equal(t, 1, len(batchRequest.Objects)) + assert.Len(t, batchRequest.Objects, 1) assert.Equal(t, p.Oid, batchRequest.Objects[0].Oid) assert.Equal(t, p.Size, batchRequest.Objects[0].Size) diff --git a/modules/log/file_test.go b/modules/log/file_test.go index f1ca23d342bf..34f74598067c 100644 --- a/modules/log/file_test.go +++ b/modules/log/file_test.go @@ -51,7 +51,7 @@ func TestFileLogger(t *testing.T) { fileLogger := NewFileLogger() realFileLogger, ok := fileLogger.(*FileLogger) - assert.Equal(t, true, ok) + assert.True(t, ok) location, _ := time.LoadLocation("EST") diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index f8b84485c06d..cb1216ec946e 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -593,5 +593,5 @@ func TestIssue18471(t *testing.T) { }, strings.NewReader(data), &res) assert.NoError(t, err) - assert.Equal(t, res.String(), "783b039...da951ce") + assert.Equal(t, "783b039...da951ce", res.String()) } diff --git a/modules/packages/container/metadata_test.go b/modules/packages/container/metadata_test.go index 48809f4c99c6..195b3982cb7b 100644 --- a/modules/packages/container/metadata_test.go +++ b/modules/packages/container/metadata_test.go @@ -33,7 +33,7 @@ func TestParseImageConfig(t *testing.T) { assert.Equal(t, projectURL, metadata.ProjectURL) assert.Equal(t, repositoryURL, metadata.RepositoryURL) assert.Equal(t, documentationURL, metadata.DocumentationURL) - assert.Equal(t, []string{"do it 1", "do it 2"}, metadata.ImageLayers) + assert.ElementsMatch(t, []string{"do it 1", "do it 2"}, metadata.ImageLayers) assert.Equal( t, map[string]string{ diff --git a/modules/paginator/paginator_test.go b/modules/paginator/paginator_test.go index 41bb30533756..8a56ee5121e8 100644 --- a/modules/paginator/paginator_test.go +++ b/modules/paginator/paginator_test.go @@ -70,19 +70,19 @@ func TestPaginator(t *testing.T) { t.Run("Generate pages", func(t *testing.T) { p := New(0, 10, 1, 0) pages := p.Pages() - assert.Equal(t, 0, len(pages)) + assert.Empty(t, pages) }) t.Run("Only current page", func(t *testing.T) { p := New(0, 10, 1, 1) pages := p.Pages() - assert.Equal(t, 1, len(pages)) + assert.Len(t, pages, 1) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) p = New(1, 10, 1, 1) pages = p.Pages() - assert.Equal(t, 1, len(pages)) + assert.Len(t, pages, 1) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) }) @@ -90,13 +90,13 @@ func TestPaginator(t *testing.T) { t.Run("Total page number is less or equal", func(t *testing.T) { p := New(1, 10, 1, 2) pages := p.Pages() - assert.Equal(t, 1, len(pages)) + assert.Len(t, pages, 1) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) p = New(11, 10, 1, 2) pages = p.Pages() - assert.Equal(t, 2, len(pages)) + assert.Len(t, pages, 2) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -104,7 +104,7 @@ func TestPaginator(t *testing.T) { p = New(11, 10, 2, 2) pages = p.Pages() - assert.Equal(t, 2, len(pages)) + assert.Len(t, pages, 2) assert.Equal(t, 1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -112,7 +112,7 @@ func TestPaginator(t *testing.T) { p = New(25, 10, 2, 3) pages = p.Pages() - assert.Equal(t, 3, len(pages)) + assert.Len(t, pages, 3) assert.Equal(t, 1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -125,7 +125,7 @@ func TestPaginator(t *testing.T) { // ... 2 p := New(11, 10, 2, 1) pages := p.Pages() - assert.Equal(t, 2, len(pages)) + assert.Len(t, pages, 2) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -134,7 +134,7 @@ func TestPaginator(t *testing.T) { // ... 2 3 p = New(21, 10, 2, 2) pages = p.Pages() - assert.Equal(t, 3, len(pages)) + assert.Len(t, pages, 3) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -145,7 +145,7 @@ func TestPaginator(t *testing.T) { // ... 2 3 4 p = New(31, 10, 3, 3) pages = p.Pages() - assert.Equal(t, 4, len(pages)) + assert.Len(t, pages, 4) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -158,7 +158,7 @@ func TestPaginator(t *testing.T) { // ... 3 4 5 p = New(41, 10, 4, 3) pages = p.Pages() - assert.Equal(t, 4, len(pages)) + assert.Len(t, pages, 4) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 3, pages[1].Num()) @@ -171,7 +171,7 @@ func TestPaginator(t *testing.T) { // ... 4 5 6 7 8 9 10 p = New(100, 10, 9, 7) pages = p.Pages() - assert.Equal(t, 8, len(pages)) + assert.Len(t, pages, 8) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 4, pages[1].Num()) @@ -194,7 +194,7 @@ func TestPaginator(t *testing.T) { // 1 ... p := New(21, 10, 1, 1) pages := p.Pages() - assert.Equal(t, 2, len(pages)) + assert.Len(t, pages, 2) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) assert.Equal(t, -1, pages[1].Num()) @@ -203,7 +203,7 @@ func TestPaginator(t *testing.T) { // 1 2 ... p = New(21, 10, 1, 2) pages = p.Pages() - assert.Equal(t, 3, len(pages)) + assert.Len(t, pages, 3) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -214,7 +214,7 @@ func TestPaginator(t *testing.T) { // 1 2 3 ... p = New(31, 10, 2, 3) pages = p.Pages() - assert.Equal(t, 4, len(pages)) + assert.Len(t, pages, 4) assert.Equal(t, 1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -227,7 +227,7 @@ func TestPaginator(t *testing.T) { // 1 2 3 ... p = New(41, 10, 2, 3) pages = p.Pages() - assert.Equal(t, 4, len(pages)) + assert.Len(t, pages, 4) assert.Equal(t, 1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -240,7 +240,7 @@ func TestPaginator(t *testing.T) { // 1 2 3 4 5 6 7 ... p = New(100, 10, 1, 7) pages = p.Pages() - assert.Equal(t, 8, len(pages)) + assert.Len(t, pages, 8) assert.Equal(t, 1, pages[0].Num()) assert.True(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -261,7 +261,7 @@ func TestPaginator(t *testing.T) { // 1 2 3 4 5 6 7 ... p = New(100, 10, 2, 7) pages = p.Pages() - assert.Equal(t, 8, len(pages)) + assert.Len(t, pages, 8) assert.Equal(t, 1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -284,7 +284,7 @@ func TestPaginator(t *testing.T) { // ... 2 3 ... p := New(35, 10, 2, 2) pages := p.Pages() - assert.Equal(t, 4, len(pages)) + assert.Len(t, pages, 4) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) @@ -297,7 +297,7 @@ func TestPaginator(t *testing.T) { // ... 2 3 4 ... p = New(49, 10, 3, 3) pages = p.Pages() - assert.Equal(t, 5, len(pages)) + assert.Len(t, pages, 5) assert.Equal(t, -1, pages[0].Num()) assert.False(t, pages[0].IsCurrent()) assert.Equal(t, 2, pages[1].Num()) diff --git a/modules/queue/unique_queue_disk_channel_test.go b/modules/queue/unique_queue_disk_channel_test.go index fd76163f4aac..e1a2132dd666 100644 --- a/modules/queue/unique_queue_disk_channel_test.go +++ b/modules/queue/unique_queue_disk_channel_test.go @@ -208,7 +208,7 @@ func TestPersistableChannelUniqueQueue(t *testing.T) { mapLock.Lock() assert.Equal(t, 101, len(executedInitial[name])+len(executedEmpty[name])) - assert.Equal(t, 0, len(hasEmpty[name])) + assert.Empty(t, hasEmpty[name]) mapLock.Unlock() }) close(done) diff --git a/modules/secret/secret_test.go b/modules/secret/secret_test.go index 0a189ecebf91..4b018fddb678 100644 --- a/modules/secret/secret_test.go +++ b/modules/secret/secret_test.go @@ -15,9 +15,9 @@ func TestEncryptDecrypt(t *testing.T) { hex, _ = EncryptSecret("foo", "baz") str, _ = DecryptSecret("foo", hex) - assert.Equal(t, str, "baz") + assert.Equal(t, "baz", str) hex, _ = EncryptSecret("bar", "baz") str, _ = DecryptSecret("foo", hex) - assert.NotEqual(t, str, "baz") + assert.NotEqual(t, "baz", str) } diff --git a/modules/storage/local_test.go b/modules/storage/local_test.go index 9649761a0f96..0873f8e14ef0 100644 --- a/modules/storage/local_test.go +++ b/modules/storage/local_test.go @@ -89,6 +89,6 @@ func TestLocalStorageIterator(t *testing.T) { return nil }) assert.NoError(t, err) - assert.Equal(t, count, len(expected)) + assert.Len(t, expected, count) } } diff --git a/modules/test/logchecker_test.go b/modules/test/logchecker_test.go index 1ed7f427f4bc..4dfea8c3e382 100644 --- a/modules/test/logchecker_test.go +++ b/modules/test/logchecker_test.go @@ -22,26 +22,26 @@ func TestLogChecker(t *testing.T) { log.Info("test") filtered, stopped := lc.Check(100 * time.Millisecond) - assert.EqualValues(t, []bool{false, false}, filtered) - assert.EqualValues(t, false, stopped) + assert.ElementsMatch(t, []bool{false, false}, filtered) + assert.False(t, stopped) log.Info("First") filtered, stopped = lc.Check(100 * time.Millisecond) - assert.EqualValues(t, []bool{true, false}, filtered) - assert.EqualValues(t, false, stopped) + assert.ElementsMatch(t, []bool{true, false}, filtered) + assert.False(t, stopped) log.Info("Second") filtered, stopped = lc.Check(100 * time.Millisecond) - assert.EqualValues(t, []bool{true, false}, filtered) - assert.EqualValues(t, false, stopped) + assert.ElementsMatch(t, []bool{true, false}, filtered) + assert.False(t, stopped) log.Info("Third") filtered, stopped = lc.Check(100 * time.Millisecond) - assert.EqualValues(t, []bool{true, true}, filtered) - assert.EqualValues(t, false, stopped) + assert.ElementsMatch(t, []bool{true, true}, filtered) + assert.False(t, stopped) log.Info("End") filtered, stopped = lc.Check(100 * time.Millisecond) - assert.EqualValues(t, []bool{true, true}, filtered) - assert.EqualValues(t, true, stopped) + assert.ElementsMatch(t, []bool{true, true}, filtered) + assert.True(t, stopped) } diff --git a/modules/translation/i18n/i18n_test.go b/modules/translation/i18n/i18n_test.go index 085d03811f6d..1d1be43318dc 100644 --- a/modules/translation/i18n/i18n_test.go +++ b/modules/translation/i18n/i18n_test.go @@ -51,8 +51,8 @@ sub = Changed Sub String assert.Equal(t, `test value; more text`, result) langs, descs := ls.ListLangNameDesc() - assert.Equal(t, []string{"lang1", "lang2"}, langs) - assert.Equal(t, []string{"Lang1", "Lang2"}, descs) + assert.ElementsMatch(t, []string{"lang1", "lang2"}, langs) + assert.ElementsMatch(t, []string{"Lang1", "Lang2"}, descs) found := ls.Has("lang1", "no-such") assert.False(t, found) diff --git a/modules/util/slice_test.go b/modules/util/slice_test.go index b0b771a79a8f..373c1a3b7b15 100644 --- a/modules/util/slice_test.go +++ b/modules/util/slice_test.go @@ -74,15 +74,15 @@ func TestSliceEqual(t *testing.T) { } func TestSliceRemoveAll(t *testing.T) { - assert.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 0), []int{2, 2, 3}) - assert.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 2), []int{0, 3}) - assert.Equal(t, SliceRemoveAll([]int{0, 0, 0, 0}, 0), []int{}) - assert.Equal(t, SliceRemoveAll([]int{2, 0, 2, 3}, 4), []int{2, 0, 2, 3}) - assert.Equal(t, SliceRemoveAll([]int{}, 0), []int{}) - assert.Equal(t, SliceRemoveAll([]int(nil), 0), []int(nil)) - assert.Equal(t, SliceRemoveAll([]int{}, 0), []int{}) - - assert.Equal(t, SliceRemoveAll([]string{"2", "0", "2", "3"}, "0"), []string{"2", "2", "3"}) - assert.Equal(t, SliceRemoveAll([]float64{2, 0, 2, 3}, 0), []float64{2, 2, 3}) - assert.Equal(t, SliceRemoveAll([]bool{false, true, false}, true), []bool{false, false}) + assert.ElementsMatch(t, []int{2, 2, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 0)) + assert.ElementsMatch(t, []int{0, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 2)) + assert.Empty(t, SliceRemoveAll([]int{0, 0, 0, 0}, 0)) + assert.ElementsMatch(t, []int{2, 0, 2, 3}, SliceRemoveAll([]int{2, 0, 2, 3}, 4)) + assert.Empty(t, SliceRemoveAll([]int{}, 0)) + assert.ElementsMatch(t, []int(nil), SliceRemoveAll([]int(nil), 0)) + assert.Empty(t, SliceRemoveAll([]int{}, 0)) + + assert.ElementsMatch(t, []string{"2", "2", "3"}, SliceRemoveAll([]string{"2", "0", "2", "3"}, "0")) + assert.ElementsMatch(t, []float64{2, 2, 3}, SliceRemoveAll([]float64{2, 0, 2, 3}, 0)) + assert.ElementsMatch(t, []bool{false, false}, SliceRemoveAll([]bool{false, true, false}, true)) } diff --git a/modules/util/truncate_test.go b/modules/util/truncate_test.go index 05e2bc03019b..dfe1230fd447 100644 --- a/modules/util/truncate_test.go +++ b/modules/util/truncate_test.go @@ -25,7 +25,7 @@ func TestSplitString(t *testing.T) { assert.Equal(t, c.ellipsis+c.input[len(c.leftSub):], r, "test split %s at %d, expected rightSub: %q", c.input, c.n, c.input[len(c.leftSub):]) } else { assert.Equal(t, c.leftSub, l, "test split %q at %d, expected leftSub: %q", c.input, c.n, c.leftSub) - assert.Equal(t, "", r, "test split %q at %d, expected rightSub: %q", c.input, c.n, "") + assert.Empty(t, r, "test split %q at %d, expected rightSub: %q", c.input, c.n, "") } } } diff --git a/services/issue/assignee_test.go b/services/issue/assignee_test.go index 43b24e1d1fc4..f47ef45ba00f 100644 --- a/services/issue/assignee_test.go +++ b/services/issue/assignee_test.go @@ -20,7 +20,7 @@ func TestDeleteNotPassedAssignee(t *testing.T) { // Fake issue with assignees issue, err := issues_model.GetIssueWithAttrsByID(1) assert.NoError(t, err) - assert.EqualValues(t, 1, len(issue.Assignees)) + assert.Len(t, issue.Assignees, 1) user1, err := user_model.GetUserByID(db.DefaultContext, 1) // This user is already assigned (see the definition in fixtures), so running UpdateAssignee should unassign him assert.NoError(t, err) @@ -33,10 +33,10 @@ func TestDeleteNotPassedAssignee(t *testing.T) { // Clean everyone err = DeleteNotPassedAssignee(db.DefaultContext, issue, user1, []*user_model.User{}) assert.NoError(t, err) - assert.EqualValues(t, 0, len(issue.Assignees)) + assert.Empty(t, issue.Assignees) // Check they're gone assert.NoError(t, issue.LoadAssignees(db.DefaultContext)) - assert.EqualValues(t, 0, len(issue.Assignees)) + assert.Empty(t, issue.Assignees) assert.Empty(t, issue.Assignee) } diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go index da0e97c23c25..1f6a77096e8c 100644 --- a/services/issue/issue_test.go +++ b/services/issue/issue_test.go @@ -37,7 +37,7 @@ func TestIssue_DeleteIssue(t *testing.T) { issueIDs, err := issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) assert.NoError(t, err) - assert.EqualValues(t, 5, len(issueIDs)) + assert.Len(t, issueIDs, 5) issue := &issues_model.Issue{ RepoID: 1, @@ -48,7 +48,7 @@ func TestIssue_DeleteIssue(t *testing.T) { assert.NoError(t, err) issueIDs, err = issues_model.GetIssueIDsByRepoID(db.DefaultContext, 1) assert.NoError(t, err) - assert.EqualValues(t, 4, len(issueIDs)) + assert.Len(t, issueIDs, 4) // check attachment removal attachments, err := repo_model.GetAttachmentsByIssueID(db.DefaultContext, 4) @@ -57,7 +57,7 @@ func TestIssue_DeleteIssue(t *testing.T) { assert.NoError(t, err) err = deleteIssue(db.DefaultContext, issue) assert.NoError(t, err) - assert.EqualValues(t, 2, len(attachments)) + assert.Len(t, attachments, 2) for i := range attachments { attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attachments[i].UUID) assert.Error(t, err) diff --git a/services/repository/adopt_test.go b/services/repository/adopt_test.go index 3f777c425fb1..c1520e01c914 100644 --- a/services/repository/adopt_test.go +++ b/services/repository/adopt_test.go @@ -30,7 +30,7 @@ func TestCheckUnadoptedRepositories_Add(t *testing.T) { } assert.Equal(t, total, unadopted.index) - assert.Equal(t, end-start, len(unadopted.repositories)) + assert.Len(t, unadopted.repositories, end-start) } func TestCheckUnadoptedRepositories(t *testing.T) { @@ -41,7 +41,7 @@ func TestCheckUnadoptedRepositories(t *testing.T) { unadopted := &unadoptedRepositories{start: 0, end: 100} err := checkUnadoptedRepositories(db.DefaultContext, "notauser", []string{"repo"}, unadopted) assert.NoError(t, err) - assert.Equal(t, 0, len(unadopted.repositories)) + assert.Empty(t, unadopted.repositories) // // Unadopted repository is returned // Existing (adopted) repository is not returned @@ -59,7 +59,7 @@ func TestCheckUnadoptedRepositories(t *testing.T) { unadopted = &unadoptedRepositories{start: 0, end: 100} err = checkUnadoptedRepositories(db.DefaultContext, userName, []string{repoName}, unadopted) assert.NoError(t, err) - assert.Equal(t, 0, len(unadopted.repositories)) + assert.Empty(t, unadopted.repositories) assert.Equal(t, 0, unadopted.index) } diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index b608c26f6ee5..53e4849aa5e1 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -123,7 +123,7 @@ func TestAPIListUsers(t *testing.T) { } assert.True(t, found) numberOfUsers := unittest.GetCount(t, &user_model.User{}, "type = 0") - assert.Equal(t, numberOfUsers, len(users)) + assert.Len(t, users, numberOfUsers) } func TestAPIListUsersNotLoggedIn(t *testing.T) { diff --git a/tests/integration/api_comment_attachment_test.go b/tests/integration/api_comment_attachment_test.go index 1f916ffa15ce..1d0b902b3934 100644 --- a/tests/integration/api_comment_attachment_test.go +++ b/tests/integration/api_comment_attachment_test.go @@ -68,7 +68,7 @@ func TestAPIListCommentAttachments(t *testing.T) { var apiAttachments []*api.Attachment DecodeJSON(t, resp, &apiAttachments) expectedCount := unittest.GetCount(t, &repo_model.Attachment{CommentID: comment.ID}) - assert.EqualValues(t, expectedCount, len(apiAttachments)) + assert.Len(t, apiAttachments, expectedCount) unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: apiAttachments[0].ID, CommentID: comment.ID}) } diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index 70affc9899cf..56de8b59093e 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -85,7 +85,7 @@ func TestAPIListIssueComments(t *testing.T) { DecodeJSON(t, resp, &comments) expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}, unittest.Cond("type = ?", issues_model.CommentTypeComment)) - assert.EqualValues(t, expectedCount, len(comments)) + assert.Len(t, comments, expectedCount) } func TestAPICreateComment(t *testing.T) { @@ -196,5 +196,5 @@ func TestAPIListIssueTimeline(t *testing.T) { var comments []*api.TimelineComment DecodeJSON(t, resp, &comments) expectedCount := unittest.GetCount(t, &issues_model.Comment{IssueID: issue.ID}) - assert.EqualValues(t, expectedCount, len(comments)) + assert.Len(t, comments, expectedCount) } diff --git a/tests/integration/api_issue_config_test.go b/tests/integration/api_issue_config_test.go index b9b3765c4e56..f3dc663f3bee 100644 --- a/tests/integration/api_issue_config_test.go +++ b/tests/integration/api_issue_config_test.go @@ -48,5 +48,5 @@ func TestAPIReposValidateDefaultIssueConfig(t *testing.T) { DecodeJSON(t, resp, &issueConfigValidation) assert.True(t, issueConfigValidation.Valid) - assert.Equal(t, issueConfigValidation.Message, "") + assert.Empty(t, issueConfigValidation.Message) } diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index cfb56724a633..e0abf34f5e30 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -170,8 +170,8 @@ func TestAPIPullReview(t *testing.T) { DecodeJSON(t, resp, &commentReview) assert.EqualValues(t, "COMMENT", commentReview.State) assert.EqualValues(t, 2, commentReview.CodeCommentsCount) - assert.EqualValues(t, "", commentReview.Body) - assert.EqualValues(t, false, commentReview.Dismissed) + assert.Empty(t, commentReview.Body) + assert.False(t, commentReview.Dismissed) // test CreatePullReview Comment with body but without comments commentBody := "This is a body of the comment." @@ -186,7 +186,7 @@ func TestAPIPullReview(t *testing.T) { assert.EqualValues(t, "COMMENT", commentReview.State) assert.EqualValues(t, 0, commentReview.CodeCommentsCount) assert.EqualValues(t, commentBody, commentReview.Body) - assert.EqualValues(t, false, commentReview.Dismissed) + assert.False(t, commentReview.Dismissed) // test CreatePullReview Comment without body and no comments req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, token), &api.CreatePullReviewOptions{ diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go index 4b25f97dddb2..cf675f9740a2 100644 --- a/tests/integration/api_pull_test.go +++ b/tests/integration/api_pull_test.go @@ -49,12 +49,12 @@ func TestAPIViewPulls(t *testing.T) { t.Run(fmt.Sprintf("APIGetPullFiles_%d", pull.ID), doAPIGetPullFiles(ctx, pull, func(t *testing.T, files []*api.ChangedFile) { if assert.Len(t, files, 1) { - assert.EqualValues(t, "File-WoW", files[0].Filename) - assert.EqualValues(t, "", files[0].PreviousFilename) + assert.Equal(t, "File-WoW", files[0].Filename) + assert.Empty(t, files[0].PreviousFilename) assert.EqualValues(t, 1, files[0].Additions) assert.EqualValues(t, 1, files[0].Changes) assert.EqualValues(t, 0, files[0].Deletions) - assert.EqualValues(t, "added", files[0].Status) + assert.Equal(t, "added", files[0].Status) } })) } diff --git a/tests/integration/api_repo_archive_test.go b/tests/integration/api_repo_archive_test.go index fbcc12ccb62c..699d7a436c08 100644 --- a/tests/integration/api_repo_archive_test.go +++ b/tests/integration/api_repo_archive_test.go @@ -32,21 +32,21 @@ func TestAPIDownloadArchive(t *testing.T) { resp := MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) bs, err := io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, 320, len(bs)) + assert.Len(t, bs, 320) link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.tar.gz", user2.Name, repo.Name)) link.RawQuery = url.Values{"token": {token}}.Encode() resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, 266, len(bs)) + assert.Len(t, bs, 266) link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.bundle", user2.Name, repo.Name)) link.RawQuery = url.Values{"token": {token}}.Encode() resp = MakeRequest(t, NewRequest(t, "GET", link.String()), http.StatusOK) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, 382, len(bs)) + assert.Len(t, bs, 382) link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master", user2.Name, repo.Name)) link.RawQuery = url.Values{"token": {token}}.Encode() diff --git a/tests/integration/api_repo_edit_test.go b/tests/integration/api_repo_edit_test.go index 9594b86d7ef5..30dc73ef1b74 100644 --- a/tests/integration/api_repo_edit_test.go +++ b/tests/integration/api_repo_edit_test.go @@ -194,10 +194,10 @@ func TestAPIRepoEdit(t *testing.T) { // check repo1 was written to database repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) - assert.Equal(t, *repo1editedOption.HasIssues, true) + assert.True(t, *repo1editedOption.HasIssues) assert.Nil(t, repo1editedOption.ExternalTracker) assert.Equal(t, *repo1editedOption.InternalTracker, *repoEditOption.InternalTracker) - assert.Equal(t, *repo1editedOption.HasWiki, true) + assert.True(t, *repo1editedOption.HasWiki) assert.Nil(t, repo1editedOption.ExternalWiki) // Test editing repo1 to use external issue and wiki @@ -216,9 +216,9 @@ func TestAPIRepoEdit(t *testing.T) { // check repo1 was written to database repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) - assert.Equal(t, *repo1editedOption.HasIssues, true) + assert.True(t, *repo1editedOption.HasIssues) assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker) - assert.Equal(t, *repo1editedOption.HasWiki, true) + assert.True(t, *repo1editedOption.HasWiki) assert.Equal(t, *repo1editedOption.ExternalWiki, *repoEditOption.ExternalWiki) repoEditOption.ExternalTracker.ExternalTrackerStyle = "regexp" @@ -229,7 +229,7 @@ func TestAPIRepoEdit(t *testing.T) { assert.NotNil(t, repo) repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) - assert.Equal(t, *repo1editedOption.HasIssues, true) + assert.True(t, *repo1editedOption.HasIssues) assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker) // Do some tests with invalid URL for external tracker and wiki @@ -259,9 +259,9 @@ func TestAPIRepoEdit(t *testing.T) { repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) repo1editedOption = getRepoEditOptionFromRepo(repo1edited) assert.Equal(t, *repo1editedOption.Description, *repoEditOption.Description) - assert.Equal(t, *repo1editedOption.HasIssues, true) + assert.True(t, *repo1editedOption.HasIssues) assert.NotNil(t, *repo1editedOption.ExternalTracker) - assert.Equal(t, *repo1editedOption.HasWiki, true) + assert.True(t, *repo1editedOption.HasWiki) assert.NotNil(t, *repo1editedOption.ExternalWiki) // reset repo in db diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index ecaa9fe9866b..aa4e6742063e 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -412,7 +412,7 @@ func TestAPIMirrorSyncNonMirrorRepo(t *testing.T) { req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1") resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) - assert.EqualValues(t, false, repo.Mirror) + assert.False(t, repo.Mirror) req = NewRequestf(t, "POST", "/api/v1/repos/user2/repo1/mirror-sync?token=%s", token) resp = MakeRequest(t, req, http.StatusBadRequest) @@ -469,7 +469,7 @@ func testAPIRepoCreateConflict(t *testing.T, u *url.URL) { resp := httpContext.Session.MakeRequest(t, req, http.StatusConflict) respJSON := map[string]string{} DecodeJSON(t, resp, &respJSON) - assert.Equal(t, respJSON["message"], "The repository with the same name already exists.") + assert.Equal(t, "The repository with the same name already exists.", respJSON["message"]) }) } diff --git a/tests/integration/auth_ldap_test.go b/tests/integration/auth_ldap_test.go index 883c9d80a3d3..81f8d9ddd750 100644 --- a/tests/integration/auth_ldap_test.go +++ b/tests/integration/auth_ldap_test.go @@ -203,7 +203,7 @@ func TestLDAPAuthChange(t *testing.T) { host, _ := doc.Find(`input[name="host"]`).Attr("value") assert.Equal(t, host, getLDAPServerHost()) binddn, _ := doc.Find(`input[name="bind_dn"]`).Attr("value") - assert.Equal(t, binddn, "uid=gitea,ou=service,dc=planetexpress,dc=com") + assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn) req = NewRequestWithValues(t, "POST", href, buildAuthSourceLDAPPayload(csrf, "", "", "", "off")) session.MakeRequest(t, req, http.StatusSeeOther) @@ -214,7 +214,7 @@ func TestLDAPAuthChange(t *testing.T) { host, _ = doc.Find(`input[name="host"]`).Attr("value") assert.Equal(t, host, getLDAPServerHost()) binddn, _ = doc.Find(`input[name="bind_dn"]`).Attr("value") - assert.Equal(t, binddn, "uid=gitea,ou=service,dc=planetexpress,dc=com") + assert.Equal(t, "uid=gitea,ou=service,dc=planetexpress,dc=com", binddn) } func TestLDAPUserSync(t *testing.T) { @@ -397,8 +397,8 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) { assert.NoError(t, err) if user.Name == "fry" || user.Name == "leela" || user.Name == "bender" { // assert members of LDAP group "cn=ship_crew" are added to mapped teams - assert.Equal(t, len(usersOrgs), 1, "User [%s] should be member of one organization", user.Name) - assert.Equal(t, usersOrgs[0].Name, "org26", "Membership should be added to the right organization") + assert.Len(t, usersOrgs, 1, "User [%s] should be member of one organization", user.Name) + assert.Equal(t, "org26", usersOrgs[0].Name, "Membership should be added to the right organization") isMember, err := organization.IsTeamMember(db.DefaultContext, usersOrgs[0].ID, team.ID, user.ID) assert.NoError(t, err) assert.True(t, isMember, "Membership should be added to the right team") diff --git a/tests/integration/cors_test.go b/tests/integration/cors_test.go index cc2d85b41eba..e4151d1c32e7 100644 --- a/tests/integration/cors_test.go +++ b/tests/integration/cors_test.go @@ -19,5 +19,5 @@ func TestCORSNotSet(t *testing.T) { resp := session.MakeRequest(t, req, http.StatusOK) assert.Equal(t, resp.Code, http.StatusOK) corsHeader := resp.Header().Get("Access-Control-Allow-Origin") - assert.Equal(t, corsHeader, "", "Access-Control-Allow-Origin: generated header should match") // header not set + assert.Empty(t, corsHeader, "Access-Control-Allow-Origin: generated header should match") // header not set } diff --git a/tests/integration/empty_repo_test.go b/tests/integration/empty_repo_test.go index 80697c7329c0..e6e5f7b18c4f 100644 --- a/tests/integration/empty_repo_test.go +++ b/tests/integration/empty_repo_test.go @@ -49,7 +49,7 @@ func TestEmptyRepoAddFile(t *testing.T) { req := NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch) resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`) - assert.Equal(t, "", doc.AttrOr("checked", "_no_")) + assert.Empty(t, doc.AttrOr("checked", "_no_")) req = NewRequestWithValues(t, "POST", "/user30/empty/_new/"+setting.Repository.DefaultBranch, map[string]string{ "_csrf": GetCSRF(t, session, "/user/settings"), "commit_choice": "direct", @@ -76,7 +76,7 @@ func TestEmptyRepoUploadFile(t *testing.T) { req := NewRequest(t, "GET", "/user30/empty/_new/"+setting.Repository.DefaultBranch) resp := session.MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body).Find(`input[name="commit_choice"]`) - assert.Equal(t, "", doc.AttrOr("checked", "_no_")) + assert.Empty(t, doc.AttrOr("checked", "_no_")) body := &bytes.Buffer{} mpForm := multipart.NewWriter(body) diff --git a/tests/integration/git_test.go b/tests/integration/git_test.go index 95323b91c62c..8d5c0fc3902b 100644 --- a/tests/integration/git_test.go +++ b/tests/integration/git_test.go @@ -763,7 +763,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB return } assert.Equal(t, "user2/"+headBranch, pr1.HeadBranch) - assert.Equal(t, false, prMsg.HasMerged) + assert.False(t, prMsg.HasMerged) assert.Contains(t, "Testing commit 1", prMsg.Body) assert.Equal(t, commit, prMsg.Head.Sha) @@ -785,7 +785,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB return } assert.Equal(t, "user2/test/"+headBranch, pr2.HeadBranch) - assert.Equal(t, false, prMsg.HasMerged) + assert.False(t, prMsg.HasMerged) }) if pr1 == nil || pr2 == nil { @@ -829,7 +829,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - assert.Equal(t, false, prMsg.HasMerged) + assert.False(t, prMsg.HasMerged) assert.Equal(t, commit, prMsg.Head.Sha) _, _, err = git.NewCommand(git.DefaultContext, "push", "origin").AddDynamicArguments("HEAD:refs/for/master/test/" + headBranch).RunStdString(&git.RunOpts{Dir: dstPath}) @@ -841,7 +841,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB if !assert.NoError(t, err) { return } - assert.Equal(t, false, prMsg.HasMerged) + assert.False(t, prMsg.HasMerged) assert.Equal(t, commit, prMsg.Head.Sha) }) t.Run("Merge", doAPIMergePullRequest(*ctx, ctx.Username, ctx.Reponame, pr1.Index)) diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go index ee185f223802..9271f25e5f0d 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -414,7 +414,7 @@ func TestConflictChecking(t *testing.T) { assert.NoError(t, err) // Ensure conflictedFiles is populated. - assert.Equal(t, 1, len(conflictingPR.ConflictedFiles)) + assert.Len(t, conflictingPR.ConflictedFiles, 1) // Check if status is correct. assert.Equal(t, issues_model.PullRequestStatusConflict, conflictingPR.Status) // Ensure that mergeable returns false diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go index f03a3b37fd13..f2bc04864a1d 100644 --- a/tests/integration/repo_test.go +++ b/tests/integration/repo_test.go @@ -376,7 +376,7 @@ func TestMarkDownReadmeImage(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src") assert.True(t, exists, "Image not found in README") - assert.Equal(t, src, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg") + assert.Equal(t, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg", src) req = NewRequest(t, "GET", "/user2/repo1/src/branch/home-md-img-check/README.md") resp = session.MakeRequest(t, req, http.StatusOK) @@ -384,7 +384,7 @@ func TestMarkDownReadmeImage(t *testing.T) { htmlDoc = NewHTMLParser(t, resp.Body) src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src") assert.True(t, exists, "Image not found in markdown file") - assert.Equal(t, src, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg") + assert.Equal(t, "/user2/repo1/media/branch/home-md-img-check/test-fake-img.jpg", src) } func TestMarkDownReadmeImageSubfolder(t *testing.T) { @@ -399,7 +399,7 @@ func TestMarkDownReadmeImageSubfolder(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) src, exists := htmlDoc.doc.Find(`.markdown img`).Attr("src") assert.True(t, exists, "Image not found in README") - assert.Equal(t, src, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg") + assert.Equal(t, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg", src) req = NewRequest(t, "GET", "/user2/repo1/src/branch/sub-home-md-img-check/docs/README.md") resp = session.MakeRequest(t, req, http.StatusOK) @@ -407,5 +407,5 @@ func TestMarkDownReadmeImageSubfolder(t *testing.T) { htmlDoc = NewHTMLParser(t, resp.Body) src, exists = htmlDoc.doc.Find(`.markdown img`).Attr("src") assert.True(t, exists, "Image not found in markdown file") - assert.Equal(t, src, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg") + assert.Equal(t, "/user2/repo1/media/branch/sub-home-md-img-check/docs/test-fake-img.jpg", src) } From d44e1565dadd09b4cdbb924479bf6e59a4d3c403 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 23 Apr 2023 07:38:25 +0800 Subject: [PATCH 18/37] Refactor `setting.Other` and remove unused `SHOW_FOOTER_BRANDING` (#24270) The `SHOW_FOOTER_BRANDING` came from year 2015, and it seems nobody ever uses it. It only shows an GitHub icon which seems unrelated to Gitea, it doesn't do what document says. So, remove it. ## :warning: Breaking Users can now remove the key `[other].SHOW_FOOTER_BRANDING` from their app.ini. --- custom/conf/app.example.ini | 1 - .../config-cheat-sheet.en-us.md | 1 - .../config-cheat-sheet.zh-cn.md | 1 - modules/context/context.go | 3 +-- modules/context/repo.go | 4 ++-- modules/setting/other.go | 23 +++++++++++-------- modules/templates/base.go | 3 +-- modules/templates/helper.go | 2 +- routers/web/repo/view.go | 2 +- routers/web/web.go | 10 ++++---- templates/base/footer_content.tmpl | 3 --- 11 files changed, 25 insertions(+), 28 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index f9f207522c7d..29ebb4699bc1 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2340,7 +2340,6 @@ ROUTER = console ;[other] ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;SHOW_FOOTER_BRANDING = false ;; Show version information about Gitea and Go in the footer ;SHOW_FOOTER_VERSION = true ;; Show template execution time in the footer diff --git a/docs/content/doc/administration/config-cheat-sheet.en-us.md b/docs/content/doc/administration/config-cheat-sheet.en-us.md index f26e7eaa085a..772e0535e91e 100644 --- a/docs/content/doc/administration/config-cheat-sheet.en-us.md +++ b/docs/content/doc/administration/config-cheat-sheet.en-us.md @@ -1391,7 +1391,6 @@ although Github don't support this form. ## Other (`other`) -- `SHOW_FOOTER_BRANDING`: **false**: Show Gitea branding in the footer. - `SHOW_FOOTER_VERSION`: **true**: Show Gitea and Go version information in the footer. - `SHOW_FOOTER_TEMPLATE_LOAD_TIME`: **true**: Show time of template execution in the footer. - `ENABLE_SITEMAP`: **true**: Generate sitemap. diff --git a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md index 83e212f32b84..485d10623469 100644 --- a/docs/content/doc/administration/config-cheat-sheet.zh-cn.md +++ b/docs/content/doc/administration/config-cheat-sheet.zh-cn.md @@ -483,5 +483,4 @@ PROXY_HOSTS = *.github.com ## Other (`other`) -- `SHOW_FOOTER_BRANDING`: 为真则在页面底部显示Gitea的字样。 - `SHOW_FOOTER_VERSION`: 为真则在页面底部显示Gitea的版本。 diff --git a/modules/context/context.go b/modules/context/context.go index 7e986b0119e2..f262c7cce7cb 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -741,8 +741,7 @@ func Contexter(ctx context.Context) func(next http.Handler) http.Handler { ctx.Data["ShowRegistrationButton"] = setting.Service.ShowRegistrationButton ctx.Data["ShowMilestonesDashboardPage"] = setting.Service.ShowMilestonesDashboardPage - ctx.Data["ShowFooterBranding"] = setting.ShowFooterBranding - ctx.Data["ShowFooterVersion"] = setting.ShowFooterVersion + ctx.Data["ShowFooterVersion"] = setting.Other.ShowFooterVersion ctx.Data["EnableSwagger"] = setting.API.EnableSwagger ctx.Data["EnableOpenIDSignIn"] = setting.Service.EnableOpenIDSignIn diff --git a/modules/context/repo.go b/modules/context/repo.go index 1736de2e4bad..6b811054c231 100644 --- a/modules/context/repo.go +++ b/modules/context/repo.go @@ -452,7 +452,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { userName := ctx.Params(":username") repoName := ctx.Params(":reponame") repoName = strings.TrimSuffix(repoName, ".git") - if setting.EnableFeed { + if setting.Other.EnableFeed { repoName = strings.TrimSuffix(repoName, ".rss") repoName = strings.TrimSuffix(repoName, ".atom") } @@ -540,7 +540,7 @@ func RepoAssignment(ctx *Context) (cancel context.CancelFunc) { ctx.Data["RepoLink"] = ctx.Repo.RepoLink ctx.Data["RepoRelPath"] = ctx.Repo.Owner.Name + "/" + ctx.Repo.Repository.Name - if setting.EnableFeed { + if setting.Other.EnableFeed { ctx.Data["EnableFeed"] = true ctx.Data["FeedURL"] = ctx.Repo.RepoLink } diff --git a/modules/setting/other.go b/modules/setting/other.go index 4fba754a0848..706cb1e3d9b8 100644 --- a/modules/setting/other.go +++ b/modules/setting/other.go @@ -3,20 +3,25 @@ package setting -var ( - // Other settings - ShowFooterBranding bool +import "code.gitea.io/gitea/modules/log" + +type OtherConfig struct { ShowFooterVersion bool ShowFooterTemplateLoadTime bool EnableFeed bool EnableSitemap bool -) +} + +var Other = OtherConfig{ + ShowFooterVersion: true, + ShowFooterTemplateLoadTime: true, + EnableSitemap: true, + EnableFeed: true, +} func loadOtherFrom(rootCfg ConfigProvider) { sec := rootCfg.Section("other") - ShowFooterBranding = sec.Key("SHOW_FOOTER_BRANDING").MustBool(false) - ShowFooterVersion = sec.Key("SHOW_FOOTER_VERSION").MustBool(true) - ShowFooterTemplateLoadTime = sec.Key("SHOW_FOOTER_TEMPLATE_LOAD_TIME").MustBool(true) - EnableSitemap = sec.Key("ENABLE_SITEMAP").MustBool(true) - EnableFeed = sec.Key("ENABLE_FEED").MustBool(true) + if err := sec.MapTo(&Other); err != nil { + log.Fatal("Failed to map [other] settings: %v", err) + } } diff --git a/modules/templates/base.go b/modules/templates/base.go index e95ce31cfcab..4254a569764e 100644 --- a/modules/templates/base.go +++ b/modules/templates/base.go @@ -33,8 +33,7 @@ func BaseVars() Vars { "ShowRegistrationButton": setting.Service.ShowRegistrationButton, "ShowMilestonesDashboardPage": setting.Service.ShowMilestonesDashboardPage, - "ShowFooterBranding": setting.ShowFooterBranding, - "ShowFooterVersion": setting.ShowFooterVersion, + "ShowFooterVersion": setting.Other.ShowFooterVersion, "DisableDownloadSourceArchives": setting.Repository.DisableDownloadSourceArchives, "EnableSwagger": setting.API.EnableSwagger, diff --git a/modules/templates/helper.go b/modules/templates/helper.go index c5b77989be24..c82f88a42f2a 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -181,7 +181,7 @@ func NewFuncMap() []template.FuncMap { return setting.UI.DefaultShowFullName }, "ShowFooterTemplateLoadTime": func() bool { - return setting.ShowFooterTemplateLoadTime + return setting.Other.ShowFooterTemplateLoadTime }, "AllowedReactions": func() []string { return setting.UI.Reactions diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 5a11073ba9a4..63e534fec0fb 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -695,7 +695,7 @@ func checkCitationFile(ctx *context.Context, entry *git.TreeEntry) { // Home render repository home page func Home(ctx *context.Context) { - if setting.EnableFeed { + if setting.Other.EnableFeed { isFeed, _, showFeedType := feed.GetFeedType(ctx.Params(":reponame"), ctx.Req) if isFeed { feed.ShowRepoFeed(ctx, ctx.Repo.Repository, showFeedType) diff --git a/routers/web/web.go b/routers/web/web.go index fc484eed4cb7..49ea63b191ec 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -293,7 +293,7 @@ func RegisterRoutes(m *web.Route) { } sitemapEnabled := func(ctx *context.Context) { - if !setting.EnableSitemap { + if !setting.Other.EnableSitemap { ctx.Error(http.StatusNotFound) return } @@ -307,7 +307,7 @@ func RegisterRoutes(m *web.Route) { } feedEnabled := func(ctx *context.Context) { - if !setting.EnableFeed { + if !setting.Other.EnableFeed { ctx.Error(http.StatusNotFound) return } @@ -706,7 +706,7 @@ func RegisterRoutes(m *web.Route) { default: context_service.UserAssignmentWeb()(ctx) if !ctx.Written() { - ctx.Data["EnableFeed"] = setting.EnableFeed + ctx.Data["EnableFeed"] = setting.Other.EnableFeed user.Profile(ctx) } } @@ -1205,7 +1205,7 @@ func RegisterRoutes(m *web.Route) { m.Get(".rss", feedEnabled, repo.TagsListFeedRSS) m.Get(".atom", feedEnabled, repo.TagsListFeedAtom) }, func(ctx *context.Context) { - ctx.Data["EnableFeed"] = setting.EnableFeed + ctx.Data["EnableFeed"] = setting.Other.EnableFeed }, repo.MustBeNotEmpty, reqRepoCodeReader, context.RepoRefByType(context.RepoRefTag, true)) m.Group("/releases", func() { m.Get("/", repo.Releases) @@ -1214,7 +1214,7 @@ func RegisterRoutes(m *web.Route) { m.Get(".rss", feedEnabled, repo.ReleasesFeedRSS) m.Get(".atom", feedEnabled, repo.ReleasesFeedAtom) }, func(ctx *context.Context) { - ctx.Data["EnableFeed"] = setting.EnableFeed + ctx.Data["EnableFeed"] = setting.Other.EnableFeed }, repo.MustBeNotEmpty, reqRepoReleaseReader, context.RepoRefByType(context.RepoRefTag, true)) m.Get("/releases/attachments/{uuid}", repo.GetAttachment, repo.MustBeNotEmpty, reqRepoReleaseReader) m.Group("/releases", func() { diff --git a/templates/base/footer_content.tmpl b/templates/base/footer_content.tmpl index f282083d65d6..17c75c687405 100644 --- a/templates/base/footer_content.tmpl +++ b/templates/base/footer_content.tmpl @@ -15,9 +15,6 @@ {{end}}