diff --git a/go.mod b/go.mod
index 6d41af507d35..fa6fb911db1a 100644
--- a/go.mod
+++ b/go.mod
@@ -5,6 +5,7 @@ go 1.18
require (
code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b
code.gitea.io/sdk/gitea v0.15.1
+ codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222
gitea.com/go-chi/binding v0.0.0-20220309004920-114340dabecb
gitea.com/go-chi/cache v0.2.0
gitea.com/go-chi/captcha v0.0.0-20211013065431-70641c1a35d5
diff --git a/go.sum b/go.sum
index 124e65a727ad..7f7ed7fe2d3e 100644
--- a/go.sum
+++ b/go.sum
@@ -62,6 +62,8 @@ code.gitea.io/gitea-vet v0.2.2-0.20220122151748-48ebc902541b/go.mod h1:zcNbT/aJE
code.gitea.io/sdk/gitea v0.11.3/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
code.gitea.io/sdk/gitea v0.15.1 h1:WJreC7YYuxbn0UDaPuWIe/mtiNKTvLN8MLkaw71yx/M=
code.gitea.io/sdk/gitea v0.15.1/go.mod h1:klY2LVI3s3NChzIk/MzMn7G1FHrfU7qd63iSMVoHRBA=
+codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222 h1:PCW4i+gnQ9XxF8V+nBch3KWdGe4MiP3xXUCA/z0jhHk=
+codeberg.org/gusted/mcaptcha v0.0.0-20220722211632-55c1ffff1222/go.mod h1:IIAjsijsd8q1isWX8MACefDEgTQslQ4stk2AeeTt3kM=
contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA=
contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0=
contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw=
diff --git a/integrations/admin_user_test.go b/integrations/admin_user_test.go
index a2020652b747..2225c903df9c 100644
--- a/integrations/admin_user_test.go
+++ b/integrations/admin_user_test.go
@@ -61,7 +61,7 @@ func makeRequest(t *testing.T, formData user_model.User, headerCode int) {
})
session.MakeRequest(t, req, headerCode)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: formData.ID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: formData.ID})
assert.Equal(t, formData.Name, user.Name)
assert.Equal(t, formData.LoginName, user.LoginName)
assert.Equal(t, formData.Email, user.Email)
diff --git a/integrations/api_admin_test.go b/integrations/api_admin_test.go
index 62c7d7eaf7d3..e32b86684472 100644
--- a/integrations/api_admin_test.go
+++ b/integrations/api_admin_test.go
@@ -22,7 +22,7 @@ func TestAPIAdminCreateAndDeleteSSHKey(t *testing.T) {
defer prepareTestEnv(t)()
// user1 is an admin user
session := loginUser(t, "user1")
- keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User)
+ keyOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
token := getTokenForLoggedInUser(t, session)
urlStr := fmt.Sprintf("/api/v1/admin/users/%s/keys?token=%s", keyOwner.Name, token)
@@ -194,7 +194,7 @@ func TestAPIEditUser(t *testing.T) {
json.Unmarshal(resp.Body.Bytes(), &errMap)
assert.EqualValues(t, "email is not allowed to be empty string", errMap["message"].(string))
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"})
assert.False(t, user2.IsRestricted)
bTrue := true
req = NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{
@@ -205,6 +205,6 @@ func TestAPIEditUser(t *testing.T) {
Restricted: &bTrue,
})
session.MakeRequest(t, req, http.StatusOK)
- user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}).(*user_model.User)
+ user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"})
assert.True(t, user2.IsRestricted)
}
diff --git a/integrations/api_comment_test.go b/integrations/api_comment_test.go
index 7dcc0279fc2f..ac1079b02de0 100644
--- a/integrations/api_comment_test.go
+++ b/integrations/api_comment_test.go
@@ -24,10 +24,10 @@ func TestAPIListRepoComments(t *testing.T) {
defer prepareTestEnv(t)()
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
- unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ unittest.Cond("type = ?", issues_model.CommentTypeComment))
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments", repoOwner.Name, repo.Name))
@@ -70,10 +70,10 @@ func TestAPIListIssueComments(t *testing.T) {
defer prepareTestEnv(t)()
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
- unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ unittest.Cond("type = ?", issues_model.CommentTypeComment))
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/issues/%d/comments",
@@ -91,9 +91,9 @@ func TestAPICreateComment(t *testing.T) {
defer prepareTestEnv(t)()
const commentBody = "Comment body"
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -113,10 +113,10 @@ func TestAPICreateComment(t *testing.T) {
func TestAPIGetComment(t *testing.T) {
defer prepareTestEnv(t)()
- comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment)
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
assert.NoError(t, comment.LoadIssue())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: comment.Issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -142,10 +142,10 @@ func TestAPIEditComment(t *testing.T) {
const newCommentBody = "This is the new comment body"
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
- unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ unittest.Cond("type = ?", issues_model.CommentTypeComment))
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -167,10 +167,10 @@ func TestAPIDeleteComment(t *testing.T) {
defer prepareTestEnv(t)()
comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{},
- unittest.Cond("type = ?", issues_model.CommentTypeComment)).(*issues_model.Comment)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ unittest.Cond("type = ?", issues_model.CommentTypeComment))
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: comment.IssueID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -185,9 +185,9 @@ func TestAPIListIssueTimeline(t *testing.T) {
defer prepareTestEnv(t)()
// load comment
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// make request
session := loginUser(t, repoOwner.Name)
diff --git a/integrations/api_issue_label_test.go b/integrations/api_issue_label_test.go
index 9b6333b2a268..9d9fdcfbc30c 100644
--- a/integrations/api_issue_label_test.go
+++ b/integrations/api_issue_label_test.go
@@ -22,8 +22,8 @@ import (
func TestAPIModifyLabels(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/labels?token=%s", owner.Name, repo.Name, token)
@@ -37,7 +37,7 @@ func TestAPIModifyLabels(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusCreated)
apiLabel := new(api.Label)
DecodeJSON(t, resp, &apiLabel)
- dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID}).(*issues_model.Label)
+ dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, RepoID: repo.ID})
assert.EqualValues(t, dbLabel.Name, apiLabel.Name)
assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color)
@@ -91,10 +91,10 @@ func TestAPIModifyLabels(t *testing.T) {
func TestAPIAddIssueLabels(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue)
- _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2}).(*issues_model.Label)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID})
+ _ = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID, ID: 2})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -114,10 +114,10 @@ func TestAPIAddIssueLabels(t *testing.T) {
func TestAPIReplaceIssueLabels(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID}).(*issues_model.Issue)
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID}).(*issues_model.Label)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repo.ID})
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{RepoID: repo.ID})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -140,8 +140,8 @@ func TestAPIReplaceIssueLabels(t *testing.T) {
func TestAPIModifyOrgLabels(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
user := "user1"
session := loginUser(t, user)
token := getTokenForLoggedInUser(t, session)
@@ -156,7 +156,7 @@ func TestAPIModifyOrgLabels(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusCreated)
apiLabel := new(api.Label)
DecodeJSON(t, resp, &apiLabel)
- dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID}).(*issues_model.Label)
+ dbLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: apiLabel.ID, OrgID: owner.ID})
assert.EqualValues(t, dbLabel.Name, apiLabel.Name)
assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color)
diff --git a/integrations/api_issue_milestone_test.go b/integrations/api_issue_milestone_test.go
index a7f89721a5e8..ba97c99b9dd8 100644
--- a/integrations/api_issue_milestone_test.go
+++ b/integrations/api_issue_milestone_test.go
@@ -21,9 +21,9 @@ import (
func TestAPIIssuesMilestone(t *testing.T) {
defer prepareTestEnv(t)()
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: milestone.RepoID}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: milestone.RepoID})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
assert.Equal(t, int64(1), int64(milestone.NumIssues))
assert.Equal(t, structs.StateOpen, milestone.State())
diff --git a/integrations/api_issue_reaction_test.go b/integrations/api_issue_reaction_test.go
index 3834af213097..ca6b69721ce2 100644
--- a/integrations/api_issue_reaction_test.go
+++ b/integrations/api_issue_reaction_test.go
@@ -23,14 +23,14 @@ import (
func TestAPIIssuesReactions(t *testing.T) {
defer prepareTestEnv(t)()
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/reactions?token=%s",
owner.Name, issue.Repo.Name, issue.Index, token)
@@ -80,17 +80,17 @@ func TestAPIIssuesReactions(t *testing.T) {
func TestAPICommentReactions(t *testing.T) {
defer prepareTestEnv(t)()
- comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2}).(*issues_model.Comment)
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2})
_ = comment.LoadIssue()
issue := comment.Issue
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/comments/%d/reactions?token=%s",
owner.Name, issue.Repo.Name, comment.ID, token)
diff --git a/integrations/api_issue_stopwatch_test.go b/integrations/api_issue_stopwatch_test.go
index b4e5f90543a3..052a1ad9fc9b 100644
--- a/integrations/api_issue_stopwatch_test.go
+++ b/integrations/api_issue_stopwatch_test.go
@@ -21,8 +21,8 @@ import (
func TestAPIListStopWatches(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -30,8 +30,8 @@ func TestAPIListStopWatches(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
var apiWatches []*api.StopWatch
DecodeJSON(t, resp, &apiWatches)
- stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue)
+ stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID})
if assert.Len(t, apiWatches, 1) {
assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix())
assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex)
@@ -45,10 +45,10 @@ func TestAPIListStopWatches(t *testing.T) {
func TestAPIStopStopWatches(t *testing.T) {
defer prepareTestEnv(t)()
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -61,10 +61,10 @@ func TestAPIStopStopWatches(t *testing.T) {
func TestAPICancelStopWatches(t *testing.T) {
defer prepareTestEnv(t)()
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -77,10 +77,10 @@ func TestAPICancelStopWatches(t *testing.T) {
func TestAPIStartStopWatches(t *testing.T) {
defer prepareTestEnv(t)()
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_issue_subscription_test.go b/integrations/api_issue_subscription_test.go
index 2c6cddcab9e7..db3d1694d650 100644
--- a/integrations/api_issue_subscription_test.go
+++ b/integrations/api_issue_subscription_test.go
@@ -21,19 +21,19 @@ import (
func TestAPIIssueSubscriptions(t *testing.T) {
defer prepareTestEnv(t)()
- issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
- issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
- issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue)
- issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue)
- issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8}).(*issues_model.Issue)
+ issue1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ issue3 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
+ issue4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4})
+ issue5 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 8})
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue1.PosterID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
testSubscription := func(issue *issues_model.Issue, isWatching bool) {
- issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
+ issueRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/check?token=%s", issueRepo.OwnerName, issueRepo.Name, issue.Index, token)
req := NewRequest(t, "GET", urlStr)
@@ -54,7 +54,7 @@ func TestAPIIssueSubscriptions(t *testing.T) {
testSubscription(issue4, false)
testSubscription(issue5, false)
- issue1Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID}).(*repo_model.Repository)
+ issue1Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue1.RepoID})
urlStr := fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue1Repo.OwnerName, issue1Repo.Name, issue1.Index, owner.Name, token)
req := NewRequest(t, "DELETE", urlStr)
session.MakeRequest(t, req, http.StatusCreated)
@@ -64,7 +64,7 @@ func TestAPIIssueSubscriptions(t *testing.T) {
session.MakeRequest(t, req, http.StatusOK)
testSubscription(issue1, false)
- issue5Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue5.RepoID}).(*repo_model.Repository)
+ issue5Repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue5.RepoID})
urlStr = fmt.Sprintf("/api/v1/repos/%s/%s/issues/%d/subscriptions/%s?token=%s", issue5Repo.OwnerName, issue5Repo.Name, issue5.Index, owner.Name, token)
req = NewRequest(t, "PUT", urlStr)
session.MakeRequest(t, req, http.StatusCreated)
diff --git a/integrations/api_issue_test.go b/integrations/api_issue_test.go
index 5c802e8d20df..afb2f75c15fb 100644
--- a/integrations/api_issue_test.go
+++ b/integrations/api_issue_test.go
@@ -16,6 +16,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"github.com/stretchr/testify/assert"
@@ -24,8 +25,8 @@ import (
func TestAPIListIssues(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -75,8 +76,8 @@ func TestAPICreateIssue(t *testing.T) {
defer prepareTestEnv(t)()
const body, title = "apiTestBody", "apiTestTitle"
- repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User)
+ repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -99,7 +100,7 @@ func TestAPICreateIssue(t *testing.T) {
Title: title,
})
- repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.Equal(t, repoBefore.NumIssues+1, repoAfter.NumIssues)
assert.Equal(t, repoBefore.NumClosedIssues, repoAfter.NumClosedIssues)
}
@@ -107,9 +108,9 @@ func TestAPICreateIssue(t *testing.T) {
func TestAPIEditIssue(t *testing.T) {
defer prepareTestEnv(t)()
- issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue)
- repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User)
+ issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
+ repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext))
assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix))
assert.Equal(t, api.StateOpen, issueBefore.State())
@@ -138,8 +139,8 @@ func TestAPIEditIssue(t *testing.T) {
var apiIssue api.Issue
DecodeJSON(t, resp, &apiIssue)
- issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue)
- repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository)
+ issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
+ repoAfter := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID})
// check deleted user
assert.Equal(t, int64(500), issueAfter.PosterID)
@@ -171,19 +172,21 @@ func TestAPISearchIssues(t *testing.T) {
token := getUserToken(t, "user2")
+ // as this API was used in the frontend, it uses UI page size
+ expectedIssueCount := 15 // from the fixtures
+ if expectedIssueCount > setting.UI.IssuePagingNum {
+ expectedIssueCount = setting.UI.IssuePagingNum
+ }
+
link, _ := url.Parse("/api/v1/repos/issues/search")
- req := NewRequest(t, "GET", link.String()+"?token="+token)
- resp := MakeRequest(t, req, http.StatusOK)
+ query := url.Values{"token": {getUserToken(t, "user1")}}
var apiIssues []*api.Issue
- DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
- query := url.Values{"token": {token}}
link.RawQuery = query.Encode()
- req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ req := NewRequest(t, "GET", link.String())
+ resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
+ assert.Len(t, apiIssues, expectedIssueCount)
since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
before := time.Unix(999307200, 0).Format(time.RFC3339)
@@ -211,14 +214,15 @@ func TestAPISearchIssues(t *testing.T) {
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
- assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit
+ assert.Len(t, apiIssues, 17)
- query.Add("limit", "20")
+ query.Add("limit", "10")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 17)
+ assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
+ assert.Len(t, apiIssues, 10)
query = url.Values{"assigned": {"true"}, "state": {"all"}, "token": {token}}
link.RawQuery = query.Encode()
@@ -266,23 +270,21 @@ func TestAPISearchIssues(t *testing.T) {
func TestAPISearchIssuesWithLabels(t *testing.T) {
defer prepareTestEnv(t)()
- token := getUserToken(t, "user1")
+ // as this API was used in the frontend, it uses UI page size
+ expectedIssueCount := 15 // from the fixtures
+ if expectedIssueCount > setting.UI.IssuePagingNum {
+ expectedIssueCount = setting.UI.IssuePagingNum
+ }
link, _ := url.Parse("/api/v1/repos/issues/search")
- req := NewRequest(t, "GET", link.String()+"?token="+token)
- resp := MakeRequest(t, req, http.StatusOK)
+ query := url.Values{"token": {getUserToken(t, "user1")}}
var apiIssues []*api.Issue
- DecodeJSON(t, resp, &apiIssues)
-
- assert.Len(t, apiIssues, 10)
- query := url.Values{}
- query.Add("token", token)
link.RawQuery = query.Encode()
- req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ req := NewRequest(t, "GET", link.String())
+ resp := MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
+ assert.Len(t, apiIssues, expectedIssueCount)
query.Add("labels", "label1")
link.RawQuery = query.Encode()
diff --git a/integrations/api_issue_tracked_time_test.go b/integrations/api_issue_tracked_time_test.go
index a6846cb78651..504aacf000d7 100644
--- a/integrations/api_issue_tracked_time_test.go
+++ b/integrations/api_issue_tracked_time_test.go
@@ -22,8 +22,8 @@ import (
func TestAPIGetTrackedTimes(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
assert.NoError(t, issue2.LoadRepo(db.DefaultContext))
session := loginUser(t, user2.Name)
@@ -64,10 +64,10 @@ func TestAPIGetTrackedTimes(t *testing.T) {
func TestAPIDeleteTrackedTime(t *testing.T) {
defer prepareTestEnv(t)()
- time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6}).(*issues_model.TrackedTime)
- issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
+ time6 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 6})
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
assert.NoError(t, issue2.LoadRepo(db.DefaultContext))
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)
@@ -76,7 +76,7 @@ func TestAPIDeleteTrackedTime(t *testing.T) {
req := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time6.ID, token)
session.MakeRequest(t, req, http.StatusForbidden)
- time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3}).(*issues_model.TrackedTime)
+ time3 := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{ID: 3})
req = NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/issues/%d/times/%d?token=%s", user2.Name, issue2.Repo.Name, issue2.Index, time3.ID, token)
session.MakeRequest(t, req, http.StatusNoContent)
// Delete non existing time
@@ -99,10 +99,10 @@ func TestAPIDeleteTrackedTime(t *testing.T) {
func TestAPIAddTrackedTimes(t *testing.T) {
defer prepareTestEnv(t)()
- issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
+ issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
assert.NoError(t, issue2.LoadRepo(db.DefaultContext))
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, admin.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_keys_test.go b/integrations/api_keys_test.go
index 198da29b8a10..76d1122086b1 100644
--- a/integrations/api_keys_test.go
+++ b/integrations/api_keys_test.go
@@ -49,8 +49,8 @@ func TestDeleteDeployKeyNoLogin(t *testing.T) {
func TestCreateReadOnlyDeployKey(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -75,8 +75,8 @@ func TestCreateReadOnlyDeployKey(t *testing.T) {
func TestCreateReadWriteDeployKey(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -100,7 +100,7 @@ func TestCreateReadWriteDeployKey(t *testing.T) {
func TestCreateUserKey(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
session := loginUser(t, "user1")
token := url.QueryEscape(getTokenForLoggedInUser(t, session))
diff --git a/integrations/api_notification_test.go b/integrations/api_notification_test.go
index 4bf18632ca07..ad6a8af0a54e 100644
--- a/integrations/api_notification_test.go
+++ b/integrations/api_notification_test.go
@@ -21,9 +21,9 @@ import (
func TestAPINotification(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes())
session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)
@@ -127,7 +127,7 @@ func TestAPINotification(t *testing.T) {
session.MakeRequest(t, req, http.StatusResetContent)
assert.Equal(t, models.NotificationStatusUnread, thread5.Status)
- thread5 = unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification)
+ thread5 = unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5})
assert.Equal(t, models.NotificationStatusRead, thread5.Status)
// -- check notifications --
@@ -140,8 +140,8 @@ func TestAPINotification(t *testing.T) {
func TestAPINotificationPUT(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes())
session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_oauth2_apps_test.go b/integrations/api_oauth2_apps_test.go
index 2c08338b25b9..4eead582d148 100644
--- a/integrations/api_oauth2_apps_test.go
+++ b/integrations/api_oauth2_apps_test.go
@@ -27,7 +27,7 @@ func TestOAuth2Application(t *testing.T) {
}
func testAPICreateOAuth2Application(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
appBody := api.CreateOAuth2ApplicationOptions{
Name: "test-app-1",
RedirectURIs: []string{
@@ -51,7 +51,7 @@ func testAPICreateOAuth2Application(t *testing.T) {
}
func testAPIListOAuth2Applications(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -61,7 +61,7 @@ func testAPIListOAuth2Applications(t *testing.T) {
RedirectURIs: []string{
"http://www.google.com",
},
- }).(*auth.OAuth2Application)
+ })
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2?token=%s", token)
req := NewRequest(t, "GET", urlStr)
@@ -80,14 +80,14 @@ func testAPIListOAuth2Applications(t *testing.T) {
}
func testAPIDeleteOAuth2Application(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
oldApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
UID: user.ID,
Name: "test-app-1",
- }).(*auth.OAuth2Application)
+ })
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", oldApp.ID, token)
req := NewRequest(t, "DELETE", urlStr)
@@ -101,7 +101,7 @@ func testAPIDeleteOAuth2Application(t *testing.T) {
}
func testAPIGetOAuth2Application(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -111,7 +111,7 @@ func testAPIGetOAuth2Application(t *testing.T) {
RedirectURIs: []string{
"http://www.google.com",
},
- }).(*auth.OAuth2Application)
+ })
urlStr := fmt.Sprintf("/api/v1/user/applications/oauth2/%d?token=%s", existApp.ID, token)
req := NewRequest(t, "GET", urlStr)
@@ -131,7 +131,7 @@ func testAPIGetOAuth2Application(t *testing.T) {
}
func testAPIUpdateOAuth2Application(t *testing.T) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
existApp := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{
UID: user.ID,
@@ -139,7 +139,7 @@ func testAPIUpdateOAuth2Application(t *testing.T) {
RedirectURIs: []string{
"http://www.google.com",
},
- }).(*auth.OAuth2Application)
+ })
appBody := api.CreateOAuth2ApplicationOptions{
Name: "test-app-1",
diff --git a/integrations/api_packages_composer_test.go b/integrations/api_packages_composer_test.go
index 59b975408dfb..7c58ae62be6a 100644
--- a/integrations/api_packages_composer_test.go
+++ b/integrations/api_packages_composer_test.go
@@ -25,7 +25,7 @@ import (
func TestPackageComposer(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
vendorName := "gitea"
projectName := "composer-package"
diff --git a/integrations/api_packages_conan_test.go b/integrations/api_packages_conan_test.go
index 65d16801fc59..e14555d1d03d 100644
--- a/integrations/api_packages_conan_test.go
+++ b/integrations/api_packages_conan_test.go
@@ -205,7 +205,7 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha
func TestPackageConan(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
name := "ConanPackage"
version1 := "1.2"
diff --git a/integrations/api_packages_container_test.go b/integrations/api_packages_container_test.go
index 5e073f313f7a..c62ab5dbb882 100644
--- a/integrations/api_packages_container_test.go
+++ b/integrations/api_packages_container_test.go
@@ -28,7 +28,7 @@ import (
func TestPackageContainer(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
has := func(l packages_model.PackagePropertyList, name string) bool {
for _, pp := range l {
@@ -276,11 +276,23 @@ func TestPackageContainer(t *testing.T) {
}
}
- // Overwrite existing tag
+ req = NewRequest(t, "GET", fmt.Sprintf("%s/manifests/%s", url, tag))
+ addTokenAuthHeader(req, userToken)
+ MakeRequest(t, req, http.StatusOK)
+
+ pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag)
+ assert.NoError(t, err)
+ assert.EqualValues(t, 1, pv.DownloadCount)
+
+ // Overwrite existing tag should keep the download count
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/manifests/%s", url, tag), strings.NewReader(manifestContent))
addTokenAuthHeader(req, userToken)
req.Header.Set("Content-Type", oci.MediaTypeDockerManifest)
MakeRequest(t, req, http.StatusCreated)
+
+ pv, err = packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, tag)
+ assert.NoError(t, err)
+ assert.EqualValues(t, 1, pv.DownloadCount)
})
t.Run("HeadManifest", func(t *testing.T) {
diff --git a/integrations/api_packages_generic_test.go b/integrations/api_packages_generic_test.go
index adaf99e981ae..f2aff8ed240c 100644
--- a/integrations/api_packages_generic_test.go
+++ b/integrations/api_packages_generic_test.go
@@ -20,19 +20,19 @@ import (
func TestPackageGeneric(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "te-st_pac.kage"
- packageVersion := "1.0.3"
+ packageVersion := "1.0.3-te st"
filename := "fi-le_na.me"
content := []byte{1, 2, 3}
- url := fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, filename)
+ url := fmt.Sprintf("/api/packages/%s/generic/%s/%s", user.Name, packageName, packageVersion)
t.Run("Upload", func(t *testing.T) {
defer PrintCurrentTest(t)()
- req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
+ req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
AddBasicAuthHeader(req, user.Name)
MakeRequest(t, req, http.StatusCreated)
@@ -55,54 +55,139 @@ func TestPackageGeneric(t *testing.T) {
pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
assert.NoError(t, err)
assert.Equal(t, int64(len(content)), pb.Size)
- })
- t.Run("UploadExists", func(t *testing.T) {
- defer PrintCurrentTest(t)()
+ t.Run("Exists", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
- req := NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
- AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusBadRequest)
+ req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusConflict)
+ })
+
+ t.Run("Additional", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequestWithBody(t, "PUT", url+"/dummy.bin", bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusCreated)
+
+ // Check deduplication
+ pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
+ assert.NoError(t, err)
+ assert.Len(t, pfs, 2)
+ assert.Equal(t, pfs[0].BlobID, pfs[1].BlobID)
+ })
+
+ t.Run("InvalidParameter", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, "invalid+package name", packageVersion, filename), bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusBadRequest)
+
+ req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, "%20test ", filename), bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusBadRequest)
+
+ req = NewRequestWithBody(t, "PUT", fmt.Sprintf("/api/packages/%s/generic/%s/%s/%s", user.Name, packageName, packageVersion, "inval+id.na me"), bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusBadRequest)
+ })
})
t.Run("Download", func(t *testing.T) {
defer PrintCurrentTest(t)()
- req := NewRequest(t, "GET", url)
+ checkDownloadCount := func(count int64) {
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 1)
+ assert.Equal(t, count, pvs[0].DownloadCount)
+ }
+
+ checkDownloadCount(0)
+
+ req := NewRequest(t, "GET", url+"/"+filename)
resp := MakeRequest(t, req, http.StatusOK)
assert.Equal(t, content, resp.Body.Bytes())
- pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
- assert.NoError(t, err)
- assert.Len(t, pvs, 1)
- assert.Equal(t, int64(1), pvs[0].DownloadCount)
+ checkDownloadCount(1)
+
+ req = NewRequest(t, "GET", url+"/dummy.bin")
+ MakeRequest(t, req, http.StatusOK)
+
+ checkDownloadCount(2)
+
+ t.Run("NotExists", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", url+"/not.found")
+ MakeRequest(t, req, http.StatusNotFound)
+ })
})
t.Run("Delete", func(t *testing.T) {
defer PrintCurrentTest(t)()
- req := NewRequest(t, "DELETE", url)
- AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusOK)
+ t.Run("File", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
- pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
- assert.NoError(t, err)
- assert.Empty(t, pvs)
- })
+ req := NewRequest(t, "DELETE", url+"/"+filename)
+ MakeRequest(t, req, http.StatusUnauthorized)
- t.Run("DownloadNotExists", func(t *testing.T) {
- defer PrintCurrentTest(t)()
+ req = NewRequest(t, "DELETE", url+"/"+filename)
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusNoContent)
- req := NewRequest(t, "GET", url)
- MakeRequest(t, req, http.StatusNotFound)
- })
+ req = NewRequest(t, "GET", url+"/"+filename)
+ MakeRequest(t, req, http.StatusNotFound)
- t.Run("DeleteNotExists", func(t *testing.T) {
- defer PrintCurrentTest(t)()
+ req = NewRequest(t, "DELETE", url+"/"+filename)
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusNotFound)
- req := NewRequest(t, "DELETE", url)
- AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusNotFound)
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 1)
+
+ t.Run("RemovesVersion", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req = NewRequest(t, "DELETE", url+"/dummy.bin")
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusNoContent)
+
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
+ assert.NoError(t, err)
+ assert.Empty(t, pvs)
+ })
+ })
+
+ t.Run("Version", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequestWithBody(t, "PUT", url+"/"+filename, bytes.NewReader(content))
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusCreated)
+
+ req = NewRequest(t, "DELETE", url)
+ MakeRequest(t, req, http.StatusUnauthorized)
+
+ req = NewRequest(t, "DELETE", url)
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusNoContent)
+
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeGeneric)
+ assert.NoError(t, err)
+ assert.Empty(t, pvs)
+
+ req = NewRequest(t, "GET", url+"/"+filename)
+ MakeRequest(t, req, http.StatusNotFound)
+
+ req = NewRequest(t, "DELETE", url)
+ AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusNotFound)
+ })
})
}
diff --git a/integrations/api_packages_helm_test.go b/integrations/api_packages_helm_test.go
index fcf5d2f7622c..8ea5e8a7b09f 100644
--- a/integrations/api_packages_helm_test.go
+++ b/integrations/api_packages_helm_test.go
@@ -26,7 +26,7 @@ import (
func TestPackageHelm(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test-chart"
packageVersion := "1.0.3"
diff --git a/integrations/api_packages_maven_test.go b/integrations/api_packages_maven_test.go
index c7c45426859e..512039b6a567 100644
--- a/integrations/api_packages_maven_test.go
+++ b/integrations/api_packages_maven_test.go
@@ -21,7 +21,7 @@ import (
func TestPackageMaven(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
groupID := "com.gitea"
artifactID := "test-project"
@@ -42,6 +42,7 @@ func TestPackageMaven(t *testing.T) {
defer PrintCurrentTest(t)()
putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusCreated)
+ putFile(t, fmt.Sprintf("/%s/%s", packageVersion, filename), "test", http.StatusBadRequest)
putFile(t, "/maven-metadata.xml", "test", http.StatusOK)
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeMaven)
@@ -135,12 +136,14 @@ func TestPackageMaven(t *testing.T) {
pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
assert.NoError(t, err)
assert.Len(t, pfs, 2)
- i := 0
- if strings.HasSuffix(pfs[1].Name, ".pom") {
- i = 1
+ for _, pf := range pfs {
+ if strings.HasSuffix(pf.Name, ".pom") {
+ assert.Equal(t, filename+".pom", pf.Name)
+ assert.True(t, pf.IsLead)
+ } else {
+ assert.False(t, pf.IsLead)
+ }
}
- assert.Equal(t, filename+".pom", pfs[i].Name)
- assert.True(t, pfs[i].IsLead)
})
t.Run("DownloadPOM", func(t *testing.T) {
@@ -202,4 +205,13 @@ func TestPackageMaven(t *testing.T) {
assert.Equal(t, checksum, resp.Body.String())
}
})
+
+ t.Run("UploadSnapshot", func(t *testing.T) {
+ snapshotVersion := packageVersion + "-SNAPSHOT"
+
+ putFile(t, fmt.Sprintf("/%s/%s", snapshotVersion, filename), "test", http.StatusCreated)
+ putFile(t, "/maven-metadata.xml", "test", http.StatusOK)
+ putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test", http.StatusCreated)
+ putFile(t, fmt.Sprintf("/%s/maven-metadata.xml", snapshotVersion), "test-overwrite", http.StatusCreated)
+ })
}
diff --git a/integrations/api_packages_npm_test.go b/integrations/api_packages_npm_test.go
index ad88ac5da676..8b22ead6d99f 100644
--- a/integrations/api_packages_npm_test.go
+++ b/integrations/api_packages_npm_test.go
@@ -24,7 +24,7 @@ import (
func TestPackageNpm(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name)))
@@ -36,33 +36,36 @@ func TestPackageNpm(t *testing.T) {
packageDescription := "Test Description"
data := "H4sIAAAAAAAA/ytITM5OTE/VL4DQelnF+XkMVAYGBgZmJiYK2MRBwNDcSIHB2NTMwNDQzMwAqA7IMDUxA9LUdgg2UFpcklgEdAql5kD8ogCnhwio5lJQUMpLzE1VslJQcihOzi9I1S9JLS7RhSYIJR2QgrLUouLM/DyQGkM9Az1D3YIiqExKanFyUWZBCVQ2BKhVwQVJDKwosbQkI78IJO/tZ+LsbRykxFXLNdA+HwWjYBSMgpENACgAbtAACAAA"
- upload := `{
- "_id": "` + packageName + `",
- "name": "` + packageName + `",
- "description": "` + packageDescription + `",
- "dist-tags": {
- "` + packageTag + `": "` + packageVersion + `"
- },
- "versions": {
- "` + packageVersion + `": {
+
+ buildUpload := func(version string) string {
+ return `{
+ "_id": "` + packageName + `",
"name": "` + packageName + `",
- "version": "` + packageVersion + `",
"description": "` + packageDescription + `",
- "author": {
- "name": "` + packageAuthor + `"
+ "dist-tags": {
+ "` + packageTag + `": "` + version + `"
+ },
+ "versions": {
+ "` + version + `": {
+ "name": "` + packageName + `",
+ "version": "` + version + `",
+ "description": "` + packageDescription + `",
+ "author": {
+ "name": "` + packageAuthor + `"
+ },
+ "dist": {
+ "integrity": "sha512-yA4FJsVhetynGfOC1jFf79BuS+jrHbm0fhh+aHzCQkOaOBXKf9oBnC4a6DnLLnEsHQDRLYd00cwj8sCXpC+wIg==",
+ "shasum": "aaa7eaf852a948b0aa05afeda35b1badca155d90"
+ }
+ }
},
- "dist": {
- "integrity": "sha512-yA4FJsVhetynGfOC1jFf79BuS+jrHbm0fhh+aHzCQkOaOBXKf9oBnC4a6DnLLnEsHQDRLYd00cwj8sCXpC+wIg==",
- "shasum": "aaa7eaf852a948b0aa05afeda35b1badca155d90"
+ "_attachments": {
+ "` + packageName + `-` + version + `.tgz": {
+ "data": "` + data + `"
+ }
}
- }
- },
- "_attachments": {
- "` + packageName + `-` + packageVersion + `.tgz": {
- "data": "` + data + `"
- }
- }
- }`
+ }`
+ }
root := fmt.Sprintf("/api/packages/%s/npm/%s", user.Name, url.QueryEscape(packageName))
tagsRoot := fmt.Sprintf("/api/packages/%s/npm/-/package/%s/dist-tags", user.Name, url.QueryEscape(packageName))
@@ -71,7 +74,7 @@ func TestPackageNpm(t *testing.T) {
t.Run("Upload", func(t *testing.T) {
defer PrintCurrentTest(t)()
- req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
+ req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion)))
req = addTokenAuthHeader(req, token)
MakeRequest(t, req, http.StatusCreated)
@@ -103,7 +106,7 @@ func TestPackageNpm(t *testing.T) {
t.Run("UploadExists", func(t *testing.T) {
defer PrintCurrentTest(t)()
- req := NewRequestWithBody(t, "PUT", root, strings.NewReader(upload))
+ req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion)))
req = addTokenAuthHeader(req, token)
MakeRequest(t, req, http.StatusBadRequest)
})
@@ -219,4 +222,57 @@ func TestPackageNpm(t *testing.T) {
test(t, http.StatusOK, "dummy")
test(t, http.StatusOK, packageTag2)
})
+
+ t.Run("Delete", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequestWithBody(t, "PUT", root, strings.NewReader(buildUpload(packageVersion+"-dummy")))
+ req = addTokenAuthHeader(req, token)
+ MakeRequest(t, req, http.StatusCreated)
+
+ req = NewRequest(t, "PUT", root+"/-rev/dummy")
+ MakeRequest(t, req, http.StatusUnauthorized)
+
+ req = NewRequest(t, "PUT", root+"/-rev/dummy")
+ req = addTokenAuthHeader(req, token)
+ MakeRequest(t, req, http.StatusOK)
+
+ t.Run("Version", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 2)
+
+ req := NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename))
+ MakeRequest(t, req, http.StatusUnauthorized)
+
+ req = NewRequest(t, "DELETE", fmt.Sprintf("%s/-/%s/%s/-rev/dummy", root, packageVersion, filename))
+ req = addTokenAuthHeader(req, token)
+ MakeRequest(t, req, http.StatusOK)
+
+ pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 1)
+ })
+
+ t.Run("Full", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 1)
+
+ req := NewRequest(t, "DELETE", root+"/-rev/dummy")
+ MakeRequest(t, req, http.StatusUnauthorized)
+
+ req = NewRequest(t, "DELETE", root+"/-rev/dummy")
+ req = addTokenAuthHeader(req, token)
+ MakeRequest(t, req, http.StatusOK)
+
+ pvs, err = packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNpm)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 0)
+ })
+ })
}
diff --git a/integrations/api_packages_nuget_test.go b/integrations/api_packages_nuget_test.go
index e69dd0ff9b66..5b662309ea1f 100644
--- a/integrations/api_packages_nuget_test.go
+++ b/integrations/api_packages_nuget_test.go
@@ -24,9 +24,16 @@ import (
"github.com/stretchr/testify/assert"
)
+func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request {
+ request.Header.Set("X-NuGet-ApiKey", token)
+ return request
+}
+
func TestPackageNuGet(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ token := getUserToken(t, user.Name)
packageName := "test.package"
packageVersion := "1.0.3"
@@ -60,6 +67,10 @@ func TestPackageNuGet(t *testing.T) {
req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
req = AddBasicAuthHeader(req, user.Name)
+ MakeRequest(t, req, http.StatusOK)
+
+ req = NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
+ req = addNuGetAPIKeyHeader(req, token)
resp := MakeRequest(t, req, http.StatusOK)
var result nuget.ServiceIndexResponse
@@ -122,7 +133,7 @@ func TestPackageNuGet(t *testing.T) {
req = NewRequestWithBody(t, "PUT", url, bytes.NewReader(content))
req = AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusBadRequest)
+ MakeRequest(t, req, http.StatusConflict)
})
t.Run("SymbolPackage", func(t *testing.T) {
@@ -208,7 +219,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createPackage(packageName, "SymbolsPackage"))
req = AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusBadRequest)
+ MakeRequest(t, req, http.StatusConflict)
})
})
@@ -352,7 +363,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`)
req := NewRequest(t, "DELETE", fmt.Sprintf("%s/%s/%s", url, packageName, packageVersion))
req = AddBasicAuthHeader(req, user.Name)
- MakeRequest(t, req, http.StatusOK)
+ MakeRequest(t, req, http.StatusNoContent)
pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypeNuGet)
assert.NoError(t, err)
diff --git a/integrations/api_packages_pub_test.go b/integrations/api_packages_pub_test.go
new file mode 100644
index 000000000000..76d5116158e3
--- /dev/null
+++ b/integrations/api_packages_pub_test.go
@@ -0,0 +1,179 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package integrations
+
+import (
+ "archive/tar"
+ "bytes"
+ "compress/gzip"
+ "fmt"
+ "io"
+ "mime/multipart"
+ "net/http"
+ "net/http/httptest"
+ "testing"
+ "time"
+
+ "code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/models/unittest"
+ user_model "code.gitea.io/gitea/models/user"
+ pub_module "code.gitea.io/gitea/modules/packages/pub"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPackagePub(t *testing.T) {
+ defer prepareTestEnv(t)()
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+
+ token := "Bearer " + getUserToken(t, user.Name)
+
+ packageName := "test_package"
+ packageVersion := "1.0.1"
+ packageDescription := "Test Description"
+
+ filename := fmt.Sprintf("%s.tar.gz", packageVersion)
+
+ pubspecContent := `name: ` + packageName + `
+version: ` + packageVersion + `
+description: ` + packageDescription
+
+ var buf bytes.Buffer
+ zw := gzip.NewWriter(&buf)
+ archive := tar.NewWriter(zw)
+ archive.WriteHeader(&tar.Header{
+ Name: "pubspec.yaml",
+ Mode: 0o600,
+ Size: int64(len(pubspecContent)),
+ })
+ archive.Write([]byte(pubspecContent))
+ archive.Close()
+ zw.Close()
+ content := buf.Bytes()
+
+ root := fmt.Sprintf("/api/packages/%s/pub", user.Name)
+
+ t.Run("Upload", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ uploadURL := root + "/api/packages/versions/new"
+
+ req := NewRequest(t, "GET", uploadURL)
+ MakeRequest(t, req, http.StatusUnauthorized)
+
+ req = NewRequest(t, "GET", uploadURL)
+ addTokenAuthHeader(req, token)
+ resp := MakeRequest(t, req, http.StatusOK)
+
+ type UploadRequest struct {
+ URL string `json:"url"`
+ Fields map[string]string `json:"fields"`
+ }
+
+ var result UploadRequest
+ DecodeJSON(t, resp, &result)
+
+ assert.Empty(t, result.Fields)
+
+ uploadFile := func(t *testing.T, url string, content []byte, expectedStatus int) *httptest.ResponseRecorder {
+ body := &bytes.Buffer{}
+ writer := multipart.NewWriter(body)
+ part, _ := writer.CreateFormFile("file", "dummy.tar.gz")
+ _, _ = io.Copy(part, bytes.NewReader(content))
+
+ _ = writer.Close()
+
+ req := NewRequestWithBody(t, "POST", url, body)
+ req.Header.Add("Content-Type", writer.FormDataContentType())
+ addTokenAuthHeader(req, token)
+ return MakeRequest(t, req, expectedStatus)
+ }
+
+ resp = uploadFile(t, result.URL, content, http.StatusNoContent)
+
+ req = NewRequest(t, "GET", resp.Header().Get("Location"))
+ addTokenAuthHeader(req, token)
+ MakeRequest(t, req, http.StatusOK)
+
+ pvs, err := packages.GetVersionsByPackageType(db.DefaultContext, user.ID, packages.TypePub)
+ assert.NoError(t, err)
+ assert.Len(t, pvs, 1)
+
+ pd, err := packages.GetPackageDescriptor(db.DefaultContext, pvs[0])
+ assert.NoError(t, err)
+ assert.NotNil(t, pd.SemVer)
+ assert.IsType(t, &pub_module.Metadata{}, pd.Metadata)
+ assert.Equal(t, packageName, pd.Package.Name)
+ assert.Equal(t, packageVersion, pd.Version.Version)
+
+ pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID)
+ assert.NoError(t, err)
+ assert.Len(t, pfs, 1)
+ assert.Equal(t, filename, pfs[0].Name)
+ assert.True(t, pfs[0].IsLead)
+
+ pb, err := packages.GetBlobByID(db.DefaultContext, pfs[0].BlobID)
+ assert.NoError(t, err)
+ assert.Equal(t, int64(len(content)), pb.Size)
+
+ resp = uploadFile(t, result.URL, content, http.StatusBadRequest)
+ })
+
+ t.Run("Download", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s/%s", root, packageName, packageVersion))
+ resp := MakeRequest(t, req, http.StatusOK)
+
+ type VersionMetadata struct {
+ Version string `json:"version"`
+ ArchiveURL string `json:"archive_url"`
+ Published time.Time `json:"published"`
+ Pubspec interface{} `json:"pubspec,omitempty"`
+ }
+
+ var result VersionMetadata
+ DecodeJSON(t, resp, &result)
+
+ assert.Equal(t, packageVersion, result.Version)
+ assert.NotNil(t, result.Pubspec)
+
+ req = NewRequest(t, "GET", result.ArchiveURL)
+ resp = MakeRequest(t, req, http.StatusOK)
+
+ assert.Equal(t, content, resp.Body.Bytes())
+ })
+
+ t.Run("EnumeratePackageVersions", func(t *testing.T) {
+ defer PrintCurrentTest(t)()
+
+ req := NewRequest(t, "GET", fmt.Sprintf("%s/api/packages/%s", root, packageName))
+ resp := MakeRequest(t, req, http.StatusOK)
+
+ type VersionMetadata struct {
+ Version string `json:"version"`
+ ArchiveURL string `json:"archive_url"`
+ Published time.Time `json:"published"`
+ Pubspec interface{} `json:"pubspec,omitempty"`
+ }
+
+ type PackageVersions struct {
+ Name string `json:"name"`
+ Latest *VersionMetadata `json:"latest"`
+ Versions []*VersionMetadata `json:"versions"`
+ }
+
+ var result PackageVersions
+ DecodeJSON(t, resp, &result)
+
+ assert.Equal(t, packageName, result.Name)
+ assert.NotNil(t, result.Latest)
+ assert.Len(t, result.Versions, 1)
+ assert.Equal(t, result.Latest.Version, result.Versions[0].Version)
+ assert.Equal(t, packageVersion, result.Latest.Version)
+ assert.NotNil(t, result.Latest.Pubspec)
+ })
+}
diff --git a/integrations/api_packages_pypi_test.go b/integrations/api_packages_pypi_test.go
index 5d610df39da9..a4c49ef1013b 100644
--- a/integrations/api_packages_pypi_test.go
+++ b/integrations/api_packages_pypi_test.go
@@ -25,7 +25,7 @@ import (
func TestPackagePyPI(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "test-package"
packageVersion := "1.0.1"
diff --git a/integrations/api_packages_rubygems_test.go b/integrations/api_packages_rubygems_test.go
index 269bc953b418..2228d3d0c19e 100644
--- a/integrations/api_packages_rubygems_test.go
+++ b/integrations/api_packages_rubygems_test.go
@@ -23,7 +23,7 @@ import (
func TestPackageRubyGems(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
packageName := "gitea"
packageVersion := "1.0.5"
diff --git a/integrations/api_packages_test.go b/integrations/api_packages_test.go
index 1f24807060df..fcdacacea09d 100644
--- a/integrations/api_packages_test.go
+++ b/integrations/api_packages_test.go
@@ -24,7 +24,7 @@ import (
func TestPackageAPI(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_pull_commits_test.go b/integrations/api_pull_commits_test.go
index 3b75fbcb4a28..693011c2350e 100644
--- a/integrations/api_pull_commits_test.go
+++ b/integrations/api_pull_commits_test.go
@@ -18,9 +18,9 @@ import (
func TestAPIPullCommits(t *testing.T) {
defer prepareTestEnv(t)()
- pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.NoError(t, pullIssue.LoadIssue())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.HeadRepoID})
session := loginUser(t, "user2")
req := NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/commits", repo.OwnerName, repo.Name, pullIssue.Index)
diff --git a/integrations/api_pull_review_test.go b/integrations/api_pull_review_test.go
index b601ca1d41fe..024ead905062 100644
--- a/integrations/api_pull_review_test.go
+++ b/integrations/api_pull_review_test.go
@@ -21,9 +21,9 @@ import (
func TestAPIPullReview(t *testing.T) {
defer prepareTestEnv(t)()
- pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue)
+ pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID})
// test ListPullReviews
session := loginUser(t, "user2")
@@ -65,7 +65,7 @@ func TestAPIPullReview(t *testing.T) {
assert.EqualValues(t, *reviews[5], review)
// test GetPullReviewComments
- comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}).(*issues_model.Comment)
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7})
req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d/comments?token=%s", repo.OwnerName, repo.Name, pullIssue.Index, 10, token)
resp = session.MakeRequest(t, req, http.StatusOK)
var reviewComments []*api.PullReviewComment
@@ -200,9 +200,9 @@ func TestAPIPullReview(t *testing.T) {
// test get review requests
// to make it simple, use same api with get review
- pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue)
+ pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12})
assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext))
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository)
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID})
req = NewRequestf(t, http.MethodGet, "/api/v1/repos/%s/%s/pulls/%d/reviews?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token)
resp = session.MakeRequest(t, req, http.StatusOK)
@@ -224,9 +224,9 @@ func TestAPIPullReview(t *testing.T) {
func TestAPIPullReviewRequest(t *testing.T) {
defer prepareTestEnv(t)()
- pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue)
+ pullIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
assert.NoError(t, pullIssue.LoadAttributes(db.DefaultContext))
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue.RepoID})
// Test add Review Request
session := loginUser(t, "user2")
@@ -269,9 +269,9 @@ func TestAPIPullReviewRequest(t *testing.T) {
session.MakeRequest(t, req, http.StatusNoContent)
// Test team review request
- pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12}).(*issues_model.Issue)
+ pullIssue12 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 12})
assert.NoError(t, pullIssue12.LoadAttributes(db.DefaultContext))
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID}).(*repo_model.Repository)
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: pullIssue12.RepoID})
// Test add Team Review Request
req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/requested_reviewers?token=%s", repo3.OwnerName, repo3.Name, pullIssue12.Index, token), &api.PullReviewRequestOptions{
diff --git a/integrations/api_pull_test.go b/integrations/api_pull_test.go
index 0c63ec2c0065..4cb1b43cbbc2 100644
--- a/integrations/api_pull_test.go
+++ b/integrations/api_pull_test.go
@@ -23,8 +23,8 @@ import (
func TestAPIViewPulls(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, "user2")
token := getTokenForLoggedInUser(t, session)
@@ -40,9 +40,9 @@ func TestAPIViewPulls(t *testing.T) {
// TestAPIMergePullWIP ensures that we can't merge a WIP pull request
func TestAPIMergePullWIP(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false)).(*issues_model.PullRequest)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{Status: issues_model.PullRequestStatusMergeable}, unittest.Cond("has_merged = ?", false))
pr.LoadIssue()
issue_service.ChangeTitle(pr.Issue, owner, setting.Repository.PullRequest.WorkInProgressPrefixes[0]+" "+pr.Issue.Title)
@@ -63,12 +63,12 @@ func TestAPIMergePullWIP(t *testing.T) {
func TestAPICreatePullSuccess(t *testing.T) {
defer prepareTestEnv(t)()
- repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
// repo10 have code, pulls units.
- repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository)
+ repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11})
// repo11 only have code unit but should still create pulls
- owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User)
- owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User)
+ owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID})
+ owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
token := getTokenForLoggedInUser(t, session)
@@ -84,11 +84,11 @@ func TestAPICreatePullSuccess(t *testing.T) {
func TestAPICreatePullWithFieldsSuccess(t *testing.T) {
defer prepareTestEnv(t)()
// repo10 have code, pulls units.
- repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
- owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User)
+ repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
+ owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID})
// repo11 only have code unit but should still create pulls
- repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository)
- owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User)
+ repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11})
+ owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
token := getTokenForLoggedInUser(t, session)
@@ -121,11 +121,11 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) {
func TestAPICreatePullWithFieldsFailure(t *testing.T) {
defer prepareTestEnv(t)()
// repo10 have code, pulls units.
- repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
- owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User)
+ repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
+ owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID})
// repo11 only have code unit but should still create pulls
- repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11}).(*repo_model.Repository)
- owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID}).(*user_model.User)
+ repo11 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 11})
+ owner11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo11.OwnerID})
session := loginUser(t, owner11.Name)
token := getTokenForLoggedInUser(t, session)
@@ -154,8 +154,8 @@ func TestAPICreatePullWithFieldsFailure(t *testing.T) {
func TestAPIEditPull(t *testing.T) {
defer prepareTestEnv(t)()
- repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
- owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID}).(*user_model.User)
+ repo10 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
+ owner10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo10.OwnerID})
session := loginUser(t, owner10.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_releases_test.go b/integrations/api_releases_test.go
index 74639e900739..9561e3f48800 100644
--- a/integrations/api_releases_test.go
+++ b/integrations/api_releases_test.go
@@ -23,8 +23,8 @@ import (
func TestAPIListReleases(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
token := getUserToken(t, user2.LowerName)
link, _ := url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/releases", user2.Name, repo.Name))
@@ -98,8 +98,8 @@ func createNewReleaseUsingAPI(t *testing.T, session *TestSession, token string,
func TestAPICreateAndUpdateRelease(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
token := getTokenForLoggedInUser(t, session)
@@ -150,8 +150,8 @@ func TestAPICreateAndUpdateRelease(t *testing.T) {
func TestAPICreateReleaseToDefaultBranch(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
token := getTokenForLoggedInUser(t, session)
@@ -161,8 +161,8 @@ func TestAPICreateReleaseToDefaultBranch(t *testing.T) {
func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
token := getTokenForLoggedInUser(t, session)
@@ -179,8 +179,8 @@ func TestAPICreateReleaseToDefaultBranchOnExistingTag(t *testing.T) {
func TestAPIGetReleaseByTag(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
tag := "v1.1"
@@ -212,8 +212,8 @@ func TestAPIGetReleaseByTag(t *testing.T) {
func TestAPIDeleteReleaseByTagName(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_archive_test.go b/integrations/api_repo_archive_test.go
index 7778b7ff697a..ca959a12874f 100644
--- a/integrations/api_repo_archive_test.go
+++ b/integrations/api_repo_archive_test.go
@@ -21,8 +21,8 @@ import (
func TestAPIDownloadArchive(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user2.LowerName)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_collaborator_test.go b/integrations/api_repo_collaborator_test.go
index fdca1d915024..f2e5bf648d80 100644
--- a/integrations/api_repo_collaborator_test.go
+++ b/integrations/api_repo_collaborator_test.go
@@ -20,13 +20,13 @@ import (
func TestAPIRepoCollaboratorPermission(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
- repo2Owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo2.OwnerID}).(*user_model.User)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
+ repo2Owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo2.OwnerID})
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
- user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
- user10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}).(*user_model.User)
- user11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 11}).(*user_model.User)
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
+ user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
+ user10 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
+ user11 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 11})
session := loginUser(t, repo2Owner.Name)
testCtx := NewAPITestContext(t, repo2Owner.Name, repo2.Name)
diff --git a/integrations/api_repo_edit_test.go b/integrations/api_repo_edit_test.go
index f3f0139d9538..677fc0beff50 100644
--- a/integrations/api_repo_edit_test.go
+++ b/integrations/api_repo_edit_test.go
@@ -135,13 +135,13 @@ func TestAPIRepoEdit(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
bFalse, bTrue := false, true
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}).(*repo_model.Repository) // empty repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo15 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}) // empty repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
// Get user2's token
session := loginUser(t, user2.Name)
@@ -166,7 +166,7 @@ func TestAPIRepoEdit(t *testing.T) {
assert.Equal(t, *repoEditOption.Website, repo.Website)
assert.Equal(t, *repoEditOption.Archived, repo.Archived)
// check repo1 from database
- repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1edited := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo1editedOption := getRepoEditOptionFromRepo(repo1edited)
assert.Equal(t, *repoEditOption.Name, *repo1editedOption.Name)
assert.Equal(t, *repoEditOption.Description, *repo1editedOption.Description)
@@ -191,7 +191,7 @@ func TestAPIRepoEdit(t *testing.T) {
DecodeJSON(t, resp, &repo)
assert.NotNil(t, repo)
// check repo1 was written to database
- repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
assert.Equal(t, *repo1editedOption.HasIssues, true)
assert.Nil(t, repo1editedOption.ExternalTracker)
@@ -213,7 +213,7 @@ func TestAPIRepoEdit(t *testing.T) {
DecodeJSON(t, resp, &repo)
assert.NotNil(t, repo)
// check repo1 was written to database
- repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo1editedOption = getRepoEditOptionFromRepo(repo1edited)
assert.Equal(t, *repo1editedOption.HasIssues, true)
assert.Equal(t, *repo1editedOption.ExternalTracker, *repoEditOption.ExternalTracker)
@@ -244,7 +244,7 @@ func TestAPIRepoEdit(t *testing.T) {
DecodeJSON(t, resp, &repo)
assert.NotNil(t, repo)
// check repo1 was written to database
- repo1edited = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ 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)
@@ -289,7 +289,7 @@ func TestAPIRepoEdit(t *testing.T) {
_ = session.MakeRequest(t, req, http.StatusOK)
// Test making a repo public that is private
- repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository)
+ repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
assert.True(t, repo16.IsPrivate)
repoEditOption = &api.EditRepoOption{
Private: &bFalse,
@@ -297,7 +297,7 @@ func TestAPIRepoEdit(t *testing.T) {
url = fmt.Sprintf("/api/v1/repos/%s/%s?token=%s", user2.Name, repo16.Name, token2)
req = NewRequestWithJSON(t, "PATCH", url, &repoEditOption)
_ = session.MakeRequest(t, req, http.StatusOK)
- repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository)
+ repo16 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
assert.False(t, repo16.IsPrivate)
// Make it private again
repoEditOption.Private = &bTrue
@@ -311,7 +311,7 @@ func TestAPIRepoEdit(t *testing.T) {
Archived: &bTrue,
})
_ = session.MakeRequest(t, req, http.StatusOK)
- repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15}).(*repo_model.Repository)
+ repo15 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 15})
assert.True(t, repo15.IsArchived)
req = NewRequestWithJSON(t, "PATCH", url, &api.EditRepoOption{
Archived: &bFalse,
diff --git a/integrations/api_repo_file_create_test.go b/integrations/api_repo_file_create_test.go
index fd460ce5643f..f9ed479ca20e 100644
--- a/integrations/api_repo_file_create_test.go
+++ b/integrations/api_repo_file_create_test.go
@@ -112,8 +112,8 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCo
func BenchmarkAPICreateFileSmall(b *testing.B) {
onGiteaRunTB(b, func(t testing.TB, u *url.URL) {
b := t.(*testing.B)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
for n := 0; n < b.N; n++ {
treePath := fmt.Sprintf("update/file%d.txt", n)
@@ -127,8 +127,8 @@ func BenchmarkAPICreateFileMedium(b *testing.B) {
onGiteaRunTB(b, func(t testing.TB, u *url.URL) {
b := t.(*testing.B)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
b.ResetTimer()
for n := 0; n < b.N; n++ {
@@ -141,12 +141,12 @@ func BenchmarkAPICreateFileMedium(b *testing.B) {
func TestAPICreateFile(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
fileID := 0
// Get user2's token
@@ -288,7 +288,7 @@ func TestAPICreateFile(t *testing.T) {
url = fmt.Sprintf("/api/v1/repos/%s/%s/contents/%s?token=%s", user2.Name, "empty-repo", treePath, token2)
req = NewRequestWithJSON(t, "POST", url, &createFileOptions)
resp = session.MakeRequest(t, req, http.StatusCreated)
- emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}).(*repo_model.Repository) // public repo
+ emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}) // public repo
gitRepo, _ := git.OpenRepository(stdCtx.Background(), emptyRepo.RepoPath())
commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName)
latestCommit, _ := gitRepo.GetCommitByPath(treePath)
diff --git a/integrations/api_repo_file_delete_test.go b/integrations/api_repo_file_delete_test.go
index 42df869d692c..340ffe362e8d 100644
--- a/integrations/api_repo_file_delete_test.go
+++ b/integrations/api_repo_file_delete_test.go
@@ -39,12 +39,12 @@ func getDeleteFileOptions() *api.DeleteFileOptions {
func TestAPIDeleteFile(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
fileID := 0
// Get user2's token
diff --git a/integrations/api_repo_file_update_test.go b/integrations/api_repo_file_update_test.go
index e39d83e49e13..3044f0384417 100644
--- a/integrations/api_repo_file_update_test.go
+++ b/integrations/api_repo_file_update_test.go
@@ -107,12 +107,12 @@ func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string)
func TestAPIUpdateFile(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
fileID := 0
// Get user2's token
diff --git a/integrations/api_repo_get_contents_list_test.go b/integrations/api_repo_get_contents_list_test.go
index 97b152bf1b34..18231a2cafc5 100644
--- a/integrations/api_repo_get_contents_list_test.go
+++ b/integrations/api_repo_get_contents_list_test.go
@@ -55,13 +55,13 @@ func TestAPIGetContentsList(t *testing.T) {
func testAPIGetContentsList(t *testing.T, u *url.URL) {
/*** SETUP ***/
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
- treePath := "" // root dir
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
+ treePath := "" // root dir
// Get user2's token
session := loginUser(t, user2.Name)
diff --git a/integrations/api_repo_get_contents_test.go b/integrations/api_repo_get_contents_test.go
index 56f5336b7bd9..1fb8b9bf0dc3 100644
--- a/integrations/api_repo_get_contents_test.go
+++ b/integrations/api_repo_get_contents_test.go
@@ -56,12 +56,12 @@ func TestAPIGetContents(t *testing.T) {
func testAPIGetContents(t *testing.T, u *url.URL) {
/*** SETUP ***/
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3, is an org
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3, is an org
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
treePath := "README.md"
// Get user2's token
diff --git a/integrations/api_repo_git_blobs_test.go b/integrations/api_repo_git_blobs_test.go
index 0a3cf632cccd..7b990450d893 100644
--- a/integrations/api_repo_git_blobs_test.go
+++ b/integrations/api_repo_git_blobs_test.go
@@ -18,12 +18,12 @@ import (
func TestAPIReposGitBlobs(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
repo1ReadmeSHA := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
repo3ReadmeSHA := "d56a3073c1dbb7b15963110a049d50cdb5db99fc"
repo16ReadmeSHA := "f90451c72ef61a7645293d17b47be7a8e983da57"
diff --git a/integrations/api_repo_git_commits_test.go b/integrations/api_repo_git_commits_test.go
index f5a64490b9ed..7eba5bd22362 100644
--- a/integrations/api_repo_git_commits_test.go
+++ b/integrations/api_repo_git_commits_test.go
@@ -25,7 +25,7 @@ func compareCommitFiles(t *testing.T, expect []string, files []*api.CommitAffect
func TestAPIReposGitCommits(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -53,7 +53,7 @@ func TestAPIReposGitCommits(t *testing.T) {
func TestAPIReposGitCommitList(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -76,7 +76,7 @@ func TestAPIReposGitCommitList(t *testing.T) {
func TestAPIReposGitCommitListPage2Empty(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -93,7 +93,7 @@ func TestAPIReposGitCommitListPage2Empty(t *testing.T) {
func TestAPIReposGitCommitListDifferentBranch(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -112,7 +112,7 @@ func TestAPIReposGitCommitListDifferentBranch(t *testing.T) {
func TestDownloadCommitDiffOrPatch(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -134,7 +134,7 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) {
func TestGetFileHistory(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_git_hook_test.go b/integrations/api_repo_git_hook_test.go
index a31b27c45649..b90d66c175f8 100644
--- a/integrations/api_repo_git_hook_test.go
+++ b/integrations/api_repo_git_hook_test.go
@@ -25,8 +25,8 @@ echo Hello, World!
func TestAPIListGitHooks(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// user1 is an admin user
session := loginUser(t, "user1")
@@ -51,8 +51,8 @@ func TestAPIListGitHooks(t *testing.T) {
func TestAPIListGitHooksNoHooks(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// user1 is an admin user
session := loginUser(t, "user1")
@@ -72,8 +72,8 @@ func TestAPIListGitHooksNoHooks(t *testing.T) {
func TestAPIListGitHooksNoAccess(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -85,8 +85,8 @@ func TestAPIListGitHooksNoAccess(t *testing.T) {
func TestAPIGetGitHook(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// user1 is an admin user
session := loginUser(t, "user1")
@@ -103,8 +103,8 @@ func TestAPIGetGitHook(t *testing.T) {
func TestAPIGetGitHookNoAccess(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -116,8 +116,8 @@ func TestAPIGetGitHookNoAccess(t *testing.T) {
func TestAPIEditGitHook(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// user1 is an admin user
session := loginUser(t, "user1")
@@ -146,8 +146,8 @@ func TestAPIEditGitHook(t *testing.T) {
func TestAPIEditGitHookNoAccess(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -162,8 +162,8 @@ func TestAPIEditGitHookNoAccess(t *testing.T) {
func TestAPIDeleteGitHook(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 37})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
// user1 is an admin user
session := loginUser(t, "user1")
@@ -185,8 +185,8 @@ func TestAPIDeleteGitHook(t *testing.T) {
func TestAPIDeleteGitHookNoAccess(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_git_notes_test.go b/integrations/api_repo_git_notes_test.go
index 08b885bd2fc9..733e0575dce7 100644
--- a/integrations/api_repo_git_notes_test.go
+++ b/integrations/api_repo_git_notes_test.go
@@ -18,7 +18,7 @@ import (
func TestAPIReposGitNotes(t *testing.T) {
onGiteaRun(t, func(*testing.T, *url.URL) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_git_ref_test.go b/integrations/api_repo_git_ref_test.go
index f0fc3c81fa2a..7ff16eb1c5a5 100644
--- a/integrations/api_repo_git_ref_test.go
+++ b/integrations/api_repo_git_ref_test.go
@@ -14,7 +14,7 @@ import (
func TestAPIReposGitRefs(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_git_tags_test.go b/integrations/api_repo_git_tags_test.go
index 9e870d248913..45551a4d7b5c 100644
--- a/integrations/api_repo_git_tags_test.go
+++ b/integrations/api_repo_git_tags_test.go
@@ -21,8 +21,8 @@ import (
func TestAPIGitTags(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -66,8 +66,8 @@ func TestAPIGitTags(t *testing.T) {
func TestAPIDeleteTagByName(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.LowerName)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_git_trees_test.go b/integrations/api_repo_git_trees_test.go
index 03e065645bb1..d80bcadb692f 100644
--- a/integrations/api_repo_git_trees_test.go
+++ b/integrations/api_repo_git_trees_test.go
@@ -15,12 +15,12 @@ import (
func TestAPIReposGitTrees(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo1 & repo16
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of the repo3
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // owner of neither repos
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository) // public repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // public repo
- repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository) // private repo
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo1 & repo16
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of the repo3
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // owner of neither repos
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) // public repo
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // public repo
+ repo16 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}) // private repo
repo1TreeSHA := "65f1bf27bc3bf70f64657658635e66094edbcb4d"
repo3TreeSHA := "2a47ca4b614a9f5a43abbd5ad851a54a616ffee6"
repo16TreeSHA := "69554a64c1e6030f051e5c3f94bfbd773cd6a324"
diff --git a/integrations/api_repo_lfs_locks_test.go b/integrations/api_repo_lfs_locks_test.go
index ca7bd35001e5..3fd8f48f9751 100644
--- a/integrations/api_repo_lfs_locks_test.go
+++ b/integrations/api_repo_lfs_locks_test.go
@@ -23,8 +23,8 @@ import (
func TestAPILFSLocksNotStarted(t *testing.T) {
defer prepareTestEnv(t)()
setting.LFS.StartServer = false
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
MakeRequest(t, req, http.StatusNotFound)
@@ -39,8 +39,8 @@ func TestAPILFSLocksNotStarted(t *testing.T) {
func TestAPILFSLocksNotLogin(t *testing.T) {
defer prepareTestEnv(t)()
setting.LFS.StartServer = true
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/%s/%s.git/info/lfs/locks", user.Name, repo.Name)
req.Header.Set("Accept", lfs.MediaType)
@@ -53,11 +53,11 @@ func TestAPILFSLocksNotLogin(t *testing.T) {
func TestAPILFSLocksLogged(t *testing.T) {
defer prepareTestEnv(t)()
setting.LFS.StartServer = true
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // in org 3
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // in org 3
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // in org 3
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // in org 3
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository) // own by org 3
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}) // own by org 3
tests := []struct {
user *user_model.User
diff --git a/integrations/api_repo_lfs_migrate_test.go b/integrations/api_repo_lfs_migrate_test.go
index 6d41a48529ce..1f6893f32a1f 100644
--- a/integrations/api_repo_lfs_migrate_test.go
+++ b/integrations/api_repo_lfs_migrate_test.go
@@ -28,7 +28,7 @@ func TestAPIRepoLFSMigrateLocal(t *testing.T) {
setting.Migrations.AllowLocalNetworks = true
assert.NoError(t, migrations.Init())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_lfs_test.go b/integrations/api_repo_lfs_test.go
index 6a2fccebb508..8bbc01995306 100644
--- a/integrations/api_repo_lfs_test.go
+++ b/integrations/api_repo_lfs_test.go
@@ -28,8 +28,8 @@ func TestAPILFSNotStarted(t *testing.T) {
setting.LFS.StartServer = false
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "POST", "/%s/%s.git/info/lfs/objects/batch", user.Name, repo.Name)
MakeRequest(t, req, http.StatusNotFound)
@@ -48,8 +48,8 @@ func TestAPILFSMediaType(t *testing.T) {
setting.LFS.StartServer = true
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "POST", "/%s/%s.git/info/lfs/objects/batch", user.Name, repo.Name)
MakeRequest(t, req, http.StatusUnsupportedMediaType)
diff --git a/integrations/api_repo_raw_test.go b/integrations/api_repo_raw_test.go
index 258b409befb8..8e8cc750dde4 100644
--- a/integrations/api_repo_raw_test.go
+++ b/integrations/api_repo_raw_test.go
@@ -16,7 +16,7 @@ import (
func TestAPIReposRaw(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_tags_test.go b/integrations/api_repo_tags_test.go
index 14a24cf5eb75..4b87093cdf3d 100644
--- a/integrations/api_repo_tags_test.go
+++ b/integrations/api_repo_tags_test.go
@@ -19,7 +19,7 @@ import (
func TestAPIRepoTags(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Login as User2.
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/api_repo_teams_test.go b/integrations/api_repo_teams_test.go
index efd6ddb457fa..2ec69582865f 100644
--- a/integrations/api_repo_teams_test.go
+++ b/integrations/api_repo_teams_test.go
@@ -23,9 +23,9 @@ func TestAPIRepoTeams(t *testing.T) {
defer prepareTestEnv(t)()
// publicOrgRepo = user3/repo21
- publicOrgRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}).(*repo_model.Repository)
+ publicOrgRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32})
// user4
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -65,7 +65,7 @@ func TestAPIRepoTeams(t *testing.T) {
session.MakeRequest(t, req, http.StatusForbidden)
// AddTeam with user2
- user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session = loginUser(t, user.Name)
token = getTokenForLoggedInUser(t, session)
url = fmt.Sprintf("/api/v1/repos/%s/teams/%s?token=%s", publicOrgRepo.FullName(), "team1", token)
diff --git a/integrations/api_repo_test.go b/integrations/api_repo_test.go
index 57fe65f4bf90..5631df323a46 100644
--- a/integrations/api_repo_test.go
+++ b/integrations/api_repo_test.go
@@ -26,7 +26,7 @@ import (
func TestAPIUserReposNotLogin(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
req := NewRequestf(t, "GET", "/api/v1/users/%s/repos", user.Name)
resp := MakeRequest(t, req, http.StatusOK)
@@ -57,11 +57,11 @@ func TestAPISearchRepo(t *testing.T) {
assert.False(t, repo.Private)
}
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18}).(*user_model.User)
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User)
- orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 16})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 18})
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20})
+ orgUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 17})
oldAPIDefaultNum := setting.API.DefaultPagingNum
defer func() {
@@ -241,7 +241,7 @@ var repoCache = make(map[int64]*repo_model.Repository)
func getRepo(t *testing.T, repoID int64) *repo_model.Repository {
if _, ok := repoCache[repoID]; !ok {
- repoCache[repoID] = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repoCache[repoID] = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
}
return repoCache[repoID]
}
@@ -278,11 +278,11 @@ func TestAPIViewRepo(t *testing.T) {
func TestAPIOrgRepos(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
// User3 is an Org. Check their repos.
- sourceOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ sourceOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
expectedResults := map[*user_model.User]struct {
count int
@@ -324,7 +324,7 @@ func TestAPIOrgRepos(t *testing.T) {
func TestAPIGetRepoByIDUnauthorized(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
req := NewRequestf(t, "GET", "/api/v1/repositories/2?token="+token)
@@ -348,7 +348,7 @@ func TestAPIRepoMigrate(t *testing.T) {
defer prepareTestEnv(t)()
for _, testCase := range testCases {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
req := NewRequestWithJSON(t, "POST", "/api/v1/repos/migrate?token="+token, &api.MigrateRepoOptions{
@@ -448,7 +448,7 @@ func TestAPIOrgRepoCreate(t *testing.T) {
defer prepareTestEnv(t)()
for _, testCase := range testCases {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/org/%s/repos?token="+token, testCase.orgName), &api.CreateRepoOption{
@@ -515,7 +515,7 @@ func TestAPIRepoTransfer(t *testing.T) {
defer prepareTestEnv(t)()
// create repo to move
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
repoName := "moveME"
@@ -532,8 +532,8 @@ func TestAPIRepoTransfer(t *testing.T) {
// start testing
for _, testCase := range testCases {
- user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository)
+ user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: testCase.ctxUserID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
session = loginUser(t, user.Name)
token = getTokenForLoggedInUser(t, session)
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{
@@ -544,13 +544,13 @@ func TestAPIRepoTransfer(t *testing.T) {
}
// cleanup
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
_ = models.DeleteRepository(user, repo.OwnerID, repo.ID)
}
func transfer(t *testing.T) *repo_model.Repository {
// create repo to move
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
repoName := "moveME"
@@ -566,7 +566,7 @@ func transfer(t *testing.T) *repo_model.Repository {
resp := session.MakeRequest(t, req, http.StatusCreated)
DecodeJSON(t, resp, apiRepo)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiRepo.ID})
req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/transfer?token=%s", repo.OwnerName, repo.Name, token), &api.TransferRepoOption{
NewOwner: "user4",
})
@@ -630,11 +630,11 @@ func TestAPIRejectTransfer(t *testing.T) {
func TestAPIGenerateRepo(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
- templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44}).(*repo_model.Repository)
+ templateRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 44})
// user
repo := new(api.Repository)
@@ -666,10 +666,10 @@ func TestAPIGenerateRepo(t *testing.T) {
func TestAPIRepoGetReviewers(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/reviewers?token=%s", user.Name, repo.Name, token)
resp := session.MakeRequest(t, req, http.StatusOK)
@@ -680,10 +680,10 @@ func TestAPIRepoGetReviewers(t *testing.T) {
func TestAPIRepoGetAssignees(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
req := NewRequestf(t, "GET", "/api/v1/repos/%s/%s/assignees?token=%s", user.Name, repo.Name, token)
resp := session.MakeRequest(t, req, http.StatusOK)
diff --git a/integrations/api_repo_topic_test.go b/integrations/api_repo_topic_test.go
index 04295724a75b..e99c682e211f 100644
--- a/integrations/api_repo_topic_test.go
+++ b/integrations/api_repo_topic_test.go
@@ -52,11 +52,11 @@ func TestAPITopicSearch(t *testing.T) {
func TestAPIRepoTopic(t *testing.T) {
defer prepareTestEnv(t)()
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of repo2
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User) // owner of repo3
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User) // write access to repo 3
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of repo2
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}) // owner of repo3
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) // write access to repo 3
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
// Get user2's token
token2 := getUserToken(t, user2.Name)
diff --git a/integrations/api_team_test.go b/integrations/api_team_test.go
index d571342c3d61..82824d610bd6 100644
--- a/integrations/api_team_test.go
+++ b/integrations/api_team_test.go
@@ -24,9 +24,9 @@ import (
func TestAPITeam(t *testing.T) {
defer prepareTestEnv(t)()
- teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{}).(*organization.TeamUser)
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID}).(*organization.Team)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID}).(*user_model.User)
+ teamUser := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{})
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamUser.TeamID})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser.UID})
session := loginUser(t, user.Name)
token := getTokenForLoggedInUser(t, session)
@@ -39,8 +39,8 @@ func TestAPITeam(t *testing.T) {
assert.Equal(t, team.Name, apiTeam.Name)
// non team member user will not access the teams details
- teamUser2 := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 3}).(*organization.TeamUser)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser2.UID}).(*user_model.User)
+ teamUser2 := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 3})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: teamUser2.UID})
session = loginUser(t, user2.Name)
token = getTokenForLoggedInUser(t, session)
@@ -51,11 +51,11 @@ func TestAPITeam(t *testing.T) {
_ = session.MakeRequest(t, req, http.StatusUnauthorized)
// Get an admin user able to create, update and delete teams.
- user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
session = loginUser(t, user.Name)
token = getTokenForLoggedInUser(t, session)
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 6}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 6})
// Create team.
teamToCreate := &api.CreateTeamOption{
@@ -108,7 +108,7 @@ func TestAPITeam(t *testing.T) {
teamToEdit.Permission, unit.AllUnitKeyNames(), nil)
// Read team.
- teamRead := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ teamRead := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, teamRead.GetUnits())
req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID)
resp = session.MakeRequest(t, req, http.StatusOK)
@@ -174,7 +174,7 @@ func TestAPITeam(t *testing.T) {
"read", nil, teamToEdit.UnitsMap)
// Read team.
- teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ teamRead = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
req = NewRequestf(t, "GET", "/api/v1/teams/%d?token="+token, teamID)
resp = session.MakeRequest(t, req, http.StatusOK)
apiTeam = api.Team{}
@@ -207,7 +207,7 @@ func checkTeamResponse(t *testing.T, testName string, apiTeam *api.Team, name, d
}
func checkTeamBean(t *testing.T, id int64, name, description string, includesAllRepositories bool, permission string, units []string, unitsMap map[string]string) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: id}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: id})
assert.NoError(t, team.GetUnits(), "GetUnits")
apiTeam, err := convert.ToTeam(team)
assert.NoError(t, err)
@@ -222,8 +222,8 @@ type TeamSearchResults struct {
func TestAPITeamSearch(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
var results TeamSearchResults
@@ -236,7 +236,7 @@ func TestAPITeamSearch(t *testing.T) {
assert.Equal(t, "test_team", results.Data[0].Name)
// no access if not organization member
- user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
token5 := getUserToken(t, user5.Name)
req = NewRequestf(t, "GET", "/api/v1/orgs/%s/teams/search?q=%s&token=%s", org.Name, "team", token5)
@@ -246,9 +246,9 @@ func TestAPITeamSearch(t *testing.T) {
func TestAPIGetTeamRepo(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User)
- teamRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 24}).(*repo.Repository)
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
+ teamRepo := unittest.AssertExistsAndLoadBean(t, &repo.Repository{ID: 24})
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
var results api.Repository
@@ -259,7 +259,7 @@ func TestAPIGetTeamRepo(t *testing.T) {
assert.Equal(t, "big_test_private_4", teamRepo.Name)
// no access if not organization member
- user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
token5 := getUserToken(t, user5.Name)
req = NewRequestf(t, "GET", "/api/v1/teams/%d/repos/%s/?token=%s", team.ID, teamRepo.FullName(), token5)
diff --git a/integrations/api_team_user_test.go b/integrations/api_team_user_test.go
index 7263408bee56..9b3364b5b185 100644
--- a/integrations/api_team_user_test.go
+++ b/integrations/api_team_user_test.go
@@ -31,7 +31,7 @@ func TestAPITeamUser(t *testing.T) {
var user2 *api.User
DecodeJSON(t, resp, &user2)
user2.Created = user2.Created.In(time.Local)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
expectedUser := convert.ToUser(user, user)
diff --git a/integrations/api_token_test.go b/integrations/api_token_test.go
index aca4768503c9..17e8fb5e2580 100644
--- a/integrations/api_token_test.go
+++ b/integrations/api_token_test.go
@@ -17,7 +17,7 @@ import (
// TestAPICreateAndDeleteToken tests that token that was just created can be deleted
func TestAPICreateAndDeleteToken(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
req := NewRequestWithJSON(t, "POST", "/api/v1/users/user1/tokens", map[string]string{
"name": "test-key-1",
@@ -57,7 +57,7 @@ func TestAPICreateAndDeleteToken(t *testing.T) {
// TestAPIDeleteMissingToken ensures that error is thrown when token not found
func TestAPIDeleteMissingToken(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
req := NewRequestf(t, "DELETE", "/api/v1/users/user1/tokens/%d", unittest.NonexistentID)
req = AddBasicAuthHeader(req, user.Name)
diff --git a/integrations/api_user_orgs_test.go b/integrations/api_user_orgs_test.go
index 219bd273c99c..9f3487cb7fb6 100644
--- a/integrations/api_user_orgs_test.go
+++ b/integrations/api_user_orgs_test.go
@@ -25,7 +25,7 @@ func TestUserOrgs(t *testing.T) {
orgs := getUserOrgs(t, adminUsername, normalUsername)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}).(*user_model.User)
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"})
assert.Equal(t, []*api.Organization{
{
@@ -81,7 +81,7 @@ func TestMyOrgs(t *testing.T) {
resp := session.MakeRequest(t, req, http.StatusOK)
var orgs []*api.Organization
DecodeJSON(t, resp, &orgs)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"}).(*user_model.User)
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user3"})
assert.Equal(t, []*api.Organization{
{
diff --git a/integrations/api_user_search_test.go b/integrations/api_user_search_test.go
index 41f14cf944f3..dbaca24981a7 100644
--- a/integrations/api_user_search_test.go
+++ b/integrations/api_user_search_test.go
@@ -52,7 +52,7 @@ func TestAPIUserSearchNotLoggedIn(t *testing.T) {
var modelUser *user_model.User
for _, user := range results.Data {
assert.Contains(t, user.UserName, query)
- modelUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID}).(*user_model.User)
+ modelUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID})
if modelUser.KeepEmailPrivate {
assert.EqualValues(t, fmt.Sprintf("%s@%s", modelUser.LowerName, setting.Service.NoReplyAddress), user.Email)
} else {
diff --git a/integrations/auth_ldap_test.go b/integrations/auth_ldap_test.go
index 492a4fdadf3f..892ff3813401 100644
--- a/integrations/auth_ldap_test.go
+++ b/integrations/auth_ldap_test.go
@@ -326,7 +326,7 @@ func TestLDAPGroupTeamSyncAddMember(t *testing.T) {
for _, gitLDAPUser := range gitLDAPUsers {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{
Name: gitLDAPUser.UserName,
- }).(*user_model.User)
+ })
usersOrgs, err := organization.FindOrgs(organization.FindOrgOptions{
UserID: user.ID,
IncludePrivate: true,
@@ -370,7 +370,7 @@ func TestLDAPGroupTeamSyncRemoveMember(t *testing.T) {
loginUserWithPassword(t, gitLDAPUsers[0].UserName, gitLDAPUsers[0].Password)
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{
Name: gitLDAPUsers[0].UserName,
- }).(*user_model.User)
+ })
err = organization.AddOrgUser(org.ID, user.ID)
assert.NoError(t, err)
err = models.AddTeamMember(team, user.ID)
diff --git a/integrations/benchmarks_test.go b/integrations/benchmarks_test.go
index ffae471307d2..a63c36368330 100644
--- a/integrations/benchmarks_test.go
+++ b/integrations/benchmarks_test.go
@@ -33,7 +33,7 @@ func BenchmarkRepoBranchCommit(b *testing.B) {
for _, repoID := range samples {
b.StopTimer()
- repo := unittest.AssertExistsAndLoadBean(b, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(b, &repo_model.Repository{ID: repoID})
b.StartTimer()
b.Run(repo.Name, func(b *testing.B) {
session := loginUser(b, "user2")
diff --git a/integrations/change_default_branch_test.go b/integrations/change_default_branch_test.go
index 096afa28f46f..6fe7305d4563 100644
--- a/integrations/change_default_branch_test.go
+++ b/integrations/change_default_branch_test.go
@@ -16,8 +16,8 @@ import (
func TestChangeDefaultBranch(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
branchesURL := fmt.Sprintf("/%s/%s/settings/branches", owner.Name, repo.Name)
diff --git a/integrations/csrf_test.go b/integrations/csrf_test.go
index 5bfc97bbd136..2c61f954269c 100644
--- a/integrations/csrf_test.go
+++ b/integrations/csrf_test.go
@@ -20,7 +20,7 @@ func TestCsrfProtection(t *testing.T) {
defer prepareTestEnv(t)()
// test web form csrf via form
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
session := loginUser(t, user.Name)
req := NewRequestWithValues(t, "POST", "/user/settings", map[string]string{
"_csrf": "fake_csrf",
diff --git a/integrations/dump_restore_test.go b/integrations/dump_restore_test.go
index ef869c4ddabc..7395bd5bd9a7 100644
--- a/integrations/dump_restore_test.go
+++ b/integrations/dump_restore_test.go
@@ -48,8 +48,8 @@ func TestDumpRestore(t *testing.T) {
assert.NoError(t, err)
defer util.RemoveAll(basePath)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, repoOwner.Name)
token := getTokenForLoggedInUser(t, session)
@@ -90,7 +90,7 @@ func TestDumpRestore(t *testing.T) {
}, false)
assert.NoError(t, err)
- newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame}).(*repo_model.Repository)
+ newrepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: newreponame})
//
// Phase 3: dump restored from the Gitea instance to the filesystem
diff --git a/integrations/empty_repo_test.go b/integrations/empty_repo_test.go
index abc28b74c8af..daf153a183b7 100644
--- a/integrations/empty_repo_test.go
+++ b/integrations/empty_repo_test.go
@@ -21,8 +21,8 @@ func TestEmptyRepo(t *testing.T) {
"commit/1ae57b34ccf7e18373",
"graph",
}
- emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}, unittest.Cond("is_empty = ?", true)).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: emptyRepo.OwnerID}).(*user_model.User)
+ emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}, unittest.Cond("is_empty = ?", true))
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: emptyRepo.OwnerID})
for _, subpath := range subpaths {
req := NewRequestf(t, "GET", "/%s/%s/%s", owner.Name, emptyRepo.Name, subpath)
MakeRequest(t, req, http.StatusNotFound)
diff --git a/integrations/eventsource_test.go b/integrations/eventsource_test.go
index ff3298863485..e2465e9e5659 100644
--- a/integrations/eventsource_test.go
+++ b/integrations/eventsource_test.go
@@ -53,9 +53,9 @@ func TestEventSourceManagerRun(t *testing.T) {
}
}
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5}).(*models.Notification)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ thread5 := unittest.AssertExistsAndLoadBean(t, &models.Notification{ID: 5})
assert.NoError(t, thread5.LoadAttributes())
session := loginUser(t, user2.Name)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/git_test.go b/integrations/git_test.go
index d6bd673822ba..9018374514c6 100644
--- a/integrations/git_test.go
+++ b/integrations/git_test.go
@@ -156,11 +156,6 @@ func standardCommitAndPushTest(t *testing.T, dstPath string) (little, big string
func lfsCommitAndPushTest(t *testing.T, dstPath string) (littleLFS, bigLFS string) {
t.Run("LFS", func(t *testing.T) {
defer PrintCurrentTest(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
prefix := "lfs-data-file-"
err := git.NewCommand(git.DefaultContext, "lfs").AddArguments("install").Run(&git.RunOpts{Dir: dstPath})
assert.NoError(t, err)
@@ -226,7 +221,6 @@ func rawTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS s
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length)
- git.CheckLFSVersion()
if setting.LFS.StartServer {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/raw/branch/master/", littleLFS))
resp := session.MakeRequest(t, req, http.StatusOK)
@@ -268,12 +262,9 @@ func mediaTest(t *testing.T, ctx *APITestContext, little, big, littleLFS, bigLFS
resp := session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
assert.Equal(t, littleSize, resp.Length)
- git.CheckLFSVersion()
- if setting.LFS.StartServer {
- req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
- resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
- assert.Equal(t, littleSize, resp.Length)
- }
+ req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", littleLFS))
+ resp = session.MakeRequestNilResponseRecorder(t, req, http.StatusOK)
+ assert.Equal(t, littleSize, resp.Length)
if !testing.Short() {
req = NewRequest(t, "GET", path.Join("/", username, reponame, "/media/branch/master/", big))
@@ -763,7 +754,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB
pr1 = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
HeadRepoID: repo.ID,
Flow: issues_model.PullRequestFlowAGit,
- }).(*issues_model.PullRequest)
+ })
if !assert.NotEmpty(t, pr1) {
return
}
@@ -785,7 +776,7 @@ func doCreateAgitFlowPull(dstPath string, ctx *APITestContext, baseBranch, headB
HeadRepoID: repo.ID,
Index: pr1.Index + 1,
Flow: issues_model.PullRequestFlowAGit,
- }).(*issues_model.PullRequest)
+ })
if !assert.NotEmpty(t, pr2) {
return
}
diff --git a/integrations/gpg_git_test.go b/integrations/gpg_git_test.go
index 461f3c503d55..6edce606f2ba 100644
--- a/integrations/gpg_git_test.go
+++ b/integrations/gpg_git_test.go
@@ -61,7 +61,7 @@ func TestGPGGit(t *testing.T) {
setting.Repository.Signing.SigningKey = rootKeyID
setting.Repository.Signing.SigningName = "gitea"
setting.Repository.Signing.SigningEmail = "gitea@fake.local"
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: username})
setting.Repository.Signing.InitialCommit = []string{"never"}
setting.Repository.Signing.CRUDActions = []string{"never"}
diff --git a/integrations/integration_test.go b/integrations/integration_test.go
index 230f780175c9..3c379f5c84ef 100644
--- a/integrations/integration_test.go
+++ b/integrations/integration_test.go
@@ -175,10 +175,9 @@ func initIntegrationTest() {
setting.Repository.DefaultBranch = "master" // many test code still assume that default branch is called "master"
_ = util.RemoveAll(repo_module.LocalCopyPath())
- if err := git.InitOnceWithSync(context.Background()); err != nil {
+ if err := git.InitFull(context.Background()); err != nil {
log.Fatal("git.InitOnceWithSync: %v", err)
}
- git.CheckLFSVersion()
setting.InitDBConfig()
if err := storage.Init(); err != nil {
@@ -285,7 +284,6 @@ func prepareTestEnv(t testing.TB, skip ...int) func() {
assert.NoError(t, unittest.LoadFixtures())
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
- assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
@@ -586,7 +584,6 @@ func resetFixtures(t *testing.T) {
assert.NoError(t, unittest.LoadFixtures())
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
- assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
diff --git a/integrations/issue_test.go b/integrations/issue_test.go
index 7d30d657f558..4bbb4744eae9 100644
--- a/integrations/issue_test.go
+++ b/integrations/issue_test.go
@@ -41,7 +41,7 @@ func getIssue(t *testing.T, repoID int64, issueSelection *goquery.Selection) *is
indexStr := href[strings.LastIndexByte(href, '/')+1:]
index, err := strconv.Atoi(indexStr)
assert.NoError(t, err, "Invalid issue href: %s", href)
- return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)}).(*issues_model.Issue)
+ return unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: repoID, Index: int64(index)})
}
func assertMatch(t testing.TB, issue *issues_model.Issue, keyword string) {
@@ -66,8 +66,8 @@ func TestNoLoginViewIssues(t *testing.T) {
func TestViewIssuesSortByType(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
session := loginUser(t, user.Name)
req := NewRequest(t, "GET", repo.Link()+"/issues?type=created_by")
@@ -94,11 +94,11 @@ func TestViewIssuesSortByType(t *testing.T) {
func TestViewIssuesKeyword(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{
RepoID: repo.ID,
Index: 1,
- }).(*issues_model.Issue)
+ })
issues.UpdateIssueIndexer(issue)
time.Sleep(time.Second * 1)
const keyword = "first"
@@ -356,17 +356,17 @@ func TestSearchIssues(t *testing.T) {
session := loginUser(t, "user2")
+ expectedIssueCount := 15 // from the fixtures
+ if expectedIssueCount > setting.UI.IssuePagingNum {
+ expectedIssueCount = setting.UI.IssuePagingNum
+ }
+
link, _ := url.Parse("/issues/search")
req := NewRequest(t, "GET", link.String())
resp := session.MakeRequest(t, req, http.StatusOK)
var apiIssues []*api.Issue
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
-
- req = NewRequest(t, "GET", link.String())
- resp = session.MakeRequest(t, req, http.StatusOK)
- DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
+ assert.Len(t, apiIssues, expectedIssueCount)
since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801
before := time.Unix(999307200, 0).Format(time.RFC3339)
@@ -394,14 +394,15 @@ func TestSearchIssues(t *testing.T) {
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
- assert.Len(t, apiIssues, 10) // there are more but 10 is page item limit
+ assert.Len(t, apiIssues, 17)
- query.Add("limit", "20")
+ query.Add("limit", "5")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 17)
+ assert.EqualValues(t, "17", resp.Header().Get("X-Total-Count"))
+ assert.Len(t, apiIssues, 5)
query = url.Values{"assigned": {"true"}, "state": {"all"}}
link.RawQuery = query.Encode()
@@ -449,29 +450,26 @@ func TestSearchIssues(t *testing.T) {
func TestSearchIssuesWithLabels(t *testing.T) {
defer prepareTestEnv(t)()
- token := getUserToken(t, "user1")
+ expectedIssueCount := 15 // from the fixtures
+ if expectedIssueCount > setting.UI.IssuePagingNum {
+ expectedIssueCount = setting.UI.IssuePagingNum
+ }
- link, _ := url.Parse("/api/v1/repos/issues/search?token=" + token)
- req := NewRequest(t, "GET", link.String())
- resp := MakeRequest(t, req, http.StatusOK)
+ session := loginUser(t, "user1")
+ link, _ := url.Parse("/issues/search")
+ query := url.Values{}
var apiIssues []*api.Issue
- DecodeJSON(t, resp, &apiIssues)
-
- assert.Len(t, apiIssues, 10)
- query := url.Values{
- "token": []string{token},
- }
link.RawQuery = query.Encode()
- req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ req := NewRequest(t, "GET", link.String())
+ resp := session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
- assert.Len(t, apiIssues, 10)
+ assert.Len(t, apiIssues, expectedIssueCount)
query.Add("labels", "label1")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
@@ -479,7 +477,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
query.Set("labels", "label1,label2")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
@@ -487,7 +485,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
query.Set("labels", "orglabel4")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 1)
@@ -496,7 +494,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
query.Add("state", "all")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
@@ -504,7 +502,7 @@ func TestSearchIssuesWithLabels(t *testing.T) {
query.Set("labels", "label1,orglabel4")
link.RawQuery = query.Encode()
req = NewRequest(t, "GET", link.String())
- resp = MakeRequest(t, req, http.StatusOK)
+ resp = session.MakeRequest(t, req, http.StatusOK)
DecodeJSON(t, resp, &apiIssues)
assert.Len(t, apiIssues, 2)
}
@@ -512,9 +510,9 @@ func TestSearchIssuesWithLabels(t *testing.T) {
func TestGetIssueInfo(t *testing.T) {
defer prepareTestEnv(t)()
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
assert.NoError(t, issue.LoadAttributes(db.DefaultContext))
assert.Equal(t, int64(1019307200), int64(issue.DeadlineUnix))
assert.Equal(t, api.StateOpen, issue.State())
@@ -533,9 +531,9 @@ func TestGetIssueInfo(t *testing.T) {
func TestUpdateIssueDeadline(t *testing.T) {
defer prepareTestEnv(t)()
- issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}).(*issues_model.Issue)
- repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User)
+ issueBefore := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10})
+ repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issueBefore.RepoID})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
assert.NoError(t, issueBefore.LoadAttributes(db.DefaultContext))
assert.Equal(t, int64(1019307200), int64(issueBefore.DeadlineUnix))
assert.Equal(t, api.StateOpen, issueBefore.State())
diff --git a/integrations/lfs_getobject_test.go b/integrations/lfs_getobject_test.go
index 4b6bb140d3ad..14a8ac253e2c 100644
--- a/integrations/lfs_getobject_test.go
+++ b/integrations/lfs_getobject_test.go
@@ -14,7 +14,6 @@ import (
git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
- "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/setting"
@@ -83,11 +82,6 @@ func checkResponseTestContentEncoding(t *testing.T, content *[]byte, resp *httpt
func TestGetLFSSmall(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
content := []byte("A very small file\n")
resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
@@ -96,11 +90,6 @@ func TestGetLFSSmall(t *testing.T) {
func TestGetLFSLarge(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
content := make([]byte, web.GzipMinSize*10)
for i := range content {
content[i] = byte(i % 256)
@@ -112,11 +101,6 @@ func TestGetLFSLarge(t *testing.T) {
func TestGetLFSGzip(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
b := make([]byte, web.GzipMinSize*10)
for i := range b {
b[i] = byte(i % 256)
@@ -133,11 +117,6 @@ func TestGetLFSGzip(t *testing.T) {
func TestGetLFSZip(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
b := make([]byte, web.GzipMinSize*10)
for i := range b {
b[i] = byte(i % 256)
@@ -156,11 +135,6 @@ func TestGetLFSZip(t *testing.T) {
func TestGetLFSRangeNo(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
content := []byte("123456789\n")
resp := storeAndGetLfs(t, &content, nil, http.StatusOK)
@@ -169,11 +143,6 @@ func TestGetLFSRangeNo(t *testing.T) {
func TestGetLFSRange(t *testing.T) {
defer prepareTestEnv(t)()
- git.CheckLFSVersion()
- if !setting.LFS.StartServer {
- t.Skip()
- return
- }
content := []byte("123456789\n")
tests := []struct {
diff --git a/integrations/migrate_test.go b/integrations/migrate_test.go
index f67e4ed2297d..d16f74ab6df2 100644
--- a/integrations/migrate_test.go
+++ b/integrations/migrate_test.go
@@ -24,7 +24,7 @@ import (
func TestMigrateLocalPath(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User)
+ adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
old := setting.ImportLocalPaths
setting.ImportLocalPaths = true
@@ -62,7 +62,7 @@ func TestMigrateGiteaForm(t *testing.T) {
ownerName := "user2"
repoName := "repo1"
- repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName}).(*user_model.User)
+ repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: ownerName})
session := loginUser(t, ownerName)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/migration-test/migration_test.go b/integrations/migration-test/migration_test.go
index 20a5c903a92c..80093d66f1ed 100644
--- a/integrations/migration-test/migration_test.go
+++ b/integrations/migration-test/migration_test.go
@@ -82,8 +82,7 @@ func initMigrationTest(t *testing.T) func() {
}
}
- assert.NoError(t, git.InitOnceWithSync(context.Background()))
- git.CheckLFSVersion()
+ assert.NoError(t, git.InitFull(context.Background()))
setting.InitDBConfig()
setting.NewLogServices(true)
return deferFn
diff --git a/integrations/mirror_pull_test.go b/integrations/mirror_pull_test.go
index 8f74d5fe16d6..3a45fa7cc20f 100644
--- a/integrations/mirror_pull_test.go
+++ b/integrations/mirror_pull_test.go
@@ -24,8 +24,8 @@ import (
func TestMirrorPull(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
opts := migration.MigrateOptions{
diff --git a/integrations/mirror_push_test.go b/integrations/mirror_push_test.go
index 3a22b0075423..5a226c5a92f9 100644
--- a/integrations/mirror_push_test.go
+++ b/integrations/mirror_push_test.go
@@ -36,8 +36,8 @@ func testMirrorPush(t *testing.T, u *url.URL) {
setting.Migrations.AllowLocalNetworks = true
assert.NoError(t, migrations.Init())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ srcRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
mirrorRepo, err := repository.CreateRepository(user, user, models.CreateRepoOptions{
Name: "test-push-mirror",
diff --git a/integrations/org_count_test.go b/integrations/org_count_test.go
index eca51eb0f622..2bffa90034a8 100644
--- a/integrations/org_count_test.go
+++ b/integrations/org_count_test.go
@@ -115,7 +115,7 @@ func doCheckOrgCounts(username string, orgCounts map[string]int, strict bool, ca
return func(t *testing.T) {
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{
Name: username,
- }).(*user_model.User)
+ })
orgs, err := organization.FindOrgs(organization.FindOrgOptions{
UserID: user.ID,
diff --git a/integrations/org_test.go b/integrations/org_test.go
index d787e6f79100..e4677f58de76 100644
--- a/integrations/org_test.go
+++ b/integrations/org_test.go
@@ -197,8 +197,8 @@ func TestOrgRestrictedUser(t *testing.T) {
func TestTeamSearch(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
var results TeamSearchResults
@@ -213,7 +213,7 @@ func TestTeamSearch(t *testing.T) {
assert.Equal(t, "test_team", results.Data[0].Name)
// no access if not organization member
- user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
session = loginUser(t, user5.Name)
csrf = GetCSRF(t, session, "/"+org.Name)
req = NewRequestf(t, "GET", "/org/%s/teams/-/search?q=%s", org.Name, "team")
diff --git a/integrations/privateactivity_test.go b/integrations/privateactivity_test.go
index c5cdc27d6e07..8e6a538c59ab 100644
--- a/integrations/privateactivity_test.go
+++ b/integrations/privateactivity_test.go
@@ -29,8 +29,8 @@ const privateActivityTestOtherUser = "user4"
// activity helpers
func testPrivateActivityDoSomethingForActionEntries(t *testing.T) {
- repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID}).(*user_model.User)
+ repoBefore := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repoBefore.OwnerID})
session := loginUser(t, privateActivityTestUser)
token := getTokenForLoggedInUser(t, session)
diff --git a/integrations/pull_merge_test.go b/integrations/pull_merge_test.go
index 2a3a461efd12..13c2ff973a13 100644
--- a/integrations/pull_merge_test.go
+++ b/integrations/pull_merge_test.go
@@ -228,18 +228,18 @@ func TestCantMergeConflict(t *testing.T) {
// Now this PR will be marked conflict - or at least a race will do - so drop down to pure code at this point...
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{
Name: "user1",
- }).(*user_model.User)
+ })
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{
OwnerID: user1.ID,
Name: "repo1",
- }).(*repo_model.Repository)
+ })
pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{
HeadRepoID: repo1.ID,
BaseRepoID: repo1.ID,
HeadBranch: "conflict",
BaseBranch: "base",
- }).(*issues_model.PullRequest)
+ })
gitRepo, err := git.OpenRepository(git.DefaultContext, repo_model.RepoPath(user1.Name, repo1.Name))
assert.NoError(t, err)
@@ -265,11 +265,11 @@ func TestCantMergeUnrelated(t *testing.T) {
// Drop down to pure code at this point
user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{
Name: "user1",
- }).(*user_model.User)
+ })
repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{
OwnerID: user1.ID,
Name: "repo1",
- }).(*repo_model.Repository)
+ })
path := repo_model.RepoPath(user1.Name, repo1.Name)
err := git.NewCommand(git.DefaultContext, "read-tree", "--empty").Run(&git.RunOpts{Dir: path})
@@ -341,7 +341,7 @@ func TestCantMergeUnrelated(t *testing.T) {
BaseRepoID: repo1.ID,
HeadBranch: "unrelated",
BaseBranch: "base",
- }).(*issues_model.PullRequest)
+ })
err = pull.Merge(context.Background(), pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED")
assert.Error(t, err, "Merge should return an error due to unrelated")
@@ -352,7 +352,7 @@ func TestCantMergeUnrelated(t *testing.T) {
func TestConflictChecking(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Create new clean repo to test conflict checking.
baseRepo, err := repo_service.CreateRepository(user, user, models.CreateRepoOptions{
@@ -408,7 +408,7 @@ func TestConflictChecking(t *testing.T) {
err = pull.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil)
assert.NoError(t, err)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "PR with conflict!"})
conflictingPR, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID)
assert.NoError(t, err)
diff --git a/integrations/pull_status_test.go b/integrations/pull_status_test.go
index 33a27cd81275..d38d90169bff 100644
--- a/integrations/pull_status_test.go
+++ b/integrations/pull_status_test.go
@@ -56,11 +56,11 @@ func TestPullCreate_CommitStatus(t *testing.T) {
}
statesIcons := map[api.CommitStatusState]string{
- api.CommitStatusPending: "circle icon yellow",
- api.CommitStatusSuccess: "check icon green",
- api.CommitStatusError: "warning icon red",
- api.CommitStatusFailure: "remove icon red",
- api.CommitStatusWarning: "warning sign icon yellow",
+ api.CommitStatusPending: "octicon-dot-fill",
+ api.CommitStatusSuccess: "octicon-check",
+ api.CommitStatusError: "gitea-exclamation",
+ api.CommitStatusFailure: "octicon-x",
+ api.CommitStatusWarning: "gitea-exclamation",
}
testCtx := NewAPITestContext(t, "user1", "repo1")
@@ -80,9 +80,9 @@ func TestPullCreate_CommitStatus(t *testing.T) {
assert.NotEmpty(t, commitURL)
assert.EqualValues(t, commitID, path.Base(commitURL))
- cls, ok := doc.doc.Find("#commits-table tbody tr td.message i.commit-status").Last().Attr("class")
+ cls, ok := doc.doc.Find("#commits-table tbody tr td.message .commit-status").Last().Attr("class")
assert.True(t, ok)
- assert.EqualValues(t, "commit-status "+statesIcons[status], cls)
+ assert.Contains(t, cls, statesIcons[status])
}
})
}
diff --git a/integrations/pull_update_test.go b/integrations/pull_update_test.go
index 47ada91e1a08..056d06189a79 100644
--- a/integrations/pull_update_test.go
+++ b/integrations/pull_update_test.go
@@ -26,8 +26,8 @@ import (
func TestAPIPullUpdate(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// Create PR to test
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
@@ -54,8 +54,8 @@ func TestAPIPullUpdate(t *testing.T) {
func TestAPIPullUpdateByRebase(t *testing.T) {
onGiteaRun(t, func(t *testing.T, giteaURL *url.URL) {
// Create PR to test
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ org26 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 26})
pr := createOutdatedPR(t, user, org26)
// Test GetDiverging
@@ -166,7 +166,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *issues_mod
err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil)
assert.NoError(t, err)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: "Test Pull -to-update-"})
pr, err := issues_model.GetPullRequestByIssueID(db.DefaultContext, issue.ID)
assert.NoError(t, err)
diff --git a/integrations/release_test.go b/integrations/release_test.go
index dd32a64ed5c7..5c6290422d40 100644
--- a/integrations/release_test.go
+++ b/integrations/release_test.go
@@ -134,7 +134,7 @@ func TestCreateReleasePaging(t *testing.T) {
func TestViewReleaseListNoLogin(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
link := repo.Link() + "/releases"
@@ -160,7 +160,7 @@ func TestViewReleaseListNoLogin(t *testing.T) {
func TestViewReleaseListLogin(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
link := repo.Link() + "/releases"
@@ -191,7 +191,7 @@ func TestViewReleaseListLogin(t *testing.T) {
func TestViewTagsList(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
link := repo.Link() + "/tags"
diff --git a/integrations/rename_branch_test.go b/integrations/rename_branch_test.go
index 7760a2d946c4..ad27869cde04 100644
--- a/integrations/rename_branch_test.go
+++ b/integrations/rename_branch_test.go
@@ -40,6 +40,6 @@ func TestRenameBranch(t *testing.T) {
assert.Equal(t, "/user2/repo1/src/branch/main/README.md", location)
// check db
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.Equal(t, "main", repo1.DefaultBranch)
}
diff --git a/integrations/repo_commits_test.go b/integrations/repo_commits_test.go
index 7107f43b0fed..b18b35da1e65 100644
--- a/integrations/repo_commits_test.go
+++ b/integrations/repo_commits_test.go
@@ -55,7 +55,7 @@ func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) {
doc = NewHTMLParser(t, resp.Body)
// Check if commit status is displayed in message column
- sel := doc.doc.Find("#commits-table tbody tr td.message a.commit-statuses-trigger i.commit-status")
+ sel := doc.doc.Find("#commits-table tbody tr td.message a.commit-statuses-trigger .commit-status")
assert.Equal(t, 1, sel.Length())
for _, class := range classes {
assert.True(t, sel.HasClass(class))
@@ -96,21 +96,21 @@ func testRepoCommitsWithStatus(t *testing.T, resp, respOne *httptest.ResponseRec
}
func TestRepoCommitsWithStatusPending(t *testing.T) {
- doTestRepoCommitWithStatus(t, "pending", "circle", "yellow")
+ doTestRepoCommitWithStatus(t, "pending", "octicon-dot-fill", "yellow")
}
func TestRepoCommitsWithStatusSuccess(t *testing.T) {
- doTestRepoCommitWithStatus(t, "success", "check", "green")
+ doTestRepoCommitWithStatus(t, "success", "octicon-check", "green")
}
func TestRepoCommitsWithStatusError(t *testing.T) {
- doTestRepoCommitWithStatus(t, "error", "warning", "red")
+ doTestRepoCommitWithStatus(t, "error", "gitea-exclamation", "red")
}
func TestRepoCommitsWithStatusFailure(t *testing.T) {
- doTestRepoCommitWithStatus(t, "failure", "remove", "red")
+ doTestRepoCommitWithStatus(t, "failure", "octicon-x", "red")
}
func TestRepoCommitsWithStatusWarning(t *testing.T) {
- doTestRepoCommitWithStatus(t, "warning", "warning", "sign", "yellow")
+ doTestRepoCommitWithStatus(t, "warning", "gitea-exclamation", "yellow")
}
diff --git a/integrations/repo_fork_test.go b/integrations/repo_fork_test.go
index 5f28e66ac8ba..17133621d650 100644
--- a/integrations/repo_fork_test.go
+++ b/integrations/repo_fork_test.go
@@ -17,7 +17,7 @@ import (
)
func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkOwnerName, forkRepoName string) *httptest.ResponseRecorder {
- forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName}).(*user_model.User)
+ forkOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: forkOwnerName})
// Step0: check the existence of the to-fork repo
req := NewRequestf(t, "GET", "/%s/%s", forkOwnerName, forkRepoName)
diff --git a/integrations/repo_generate_test.go b/integrations/repo_generate_test.go
index 0123932a749b..d34983f528df 100644
--- a/integrations/repo_generate_test.go
+++ b/integrations/repo_generate_test.go
@@ -17,7 +17,7 @@ import (
)
func testRepoGenerate(t *testing.T, session *TestSession, templateOwnerName, templateRepoName, generateOwnerName, generateRepoName string) *httptest.ResponseRecorder {
- generateOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: generateOwnerName}).(*user_model.User)
+ generateOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: generateOwnerName})
// Step0: check the existence of the generated repo
req := NewRequestf(t, "GET", "/%s/%s", generateOwnerName, generateRepoName)
diff --git a/integrations/repo_tag_test.go b/integrations/repo_tag_test.go
index 793cf724ebff..1b3e30106bf8 100644
--- a/integrations/repo_tag_test.go
+++ b/integrations/repo_tag_test.go
@@ -24,8 +24,8 @@ import (
func TestCreateNewTagProtected(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
t.Run("API", func(t *testing.T) {
defer PrintCurrentTest(t)()
diff --git a/integrations/repo_test.go b/integrations/repo_test.go
index 872d3f24d1f7..c2ac6183f045 100644
--- a/integrations/repo_test.go
+++ b/integrations/repo_test.go
@@ -64,7 +64,7 @@ func testViewRepo(t *testing.T) {
}
})
- f.commitTime, _ = s.Find("span.time-since").Attr("title")
+ f.commitTime, _ = s.Find("span.time-since").Attr("data-content")
items = append(items, f)
})
diff --git a/integrations/signin_test.go b/integrations/signin_test.go
index 952efcfdd9d6..568ceb40ca5d 100644
--- a/integrations/signin_test.go
+++ b/integrations/signin_test.go
@@ -34,7 +34,7 @@ func testLoginFailed(t *testing.T, username, password, message string) {
func TestSignin(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// add new user with user2's email
user.Name = "testuser"
diff --git a/integrations/signup_test.go b/integrations/signup_test.go
index b34e40f28699..071ece9fa16c 100644
--- a/integrations/signup_test.go
+++ b/integrations/signup_test.go
@@ -54,7 +54,7 @@ func TestSignupAsRestricted(t *testing.T) {
req = NewRequest(t, "GET", "/restrictedUser")
MakeRequest(t, req, http.StatusOK)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "restrictedUser"}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "restrictedUser"})
assert.True(t, user2.IsRestricted)
}
diff --git a/integrations/user_avatar_test.go b/integrations/user_avatar_test.go
index 2bf6fde5ff1d..ee532bb64a27 100644
--- a/integrations/user_avatar_test.go
+++ b/integrations/user_avatar_test.go
@@ -22,7 +22,7 @@ import (
func TestUserAvatar(t *testing.T) {
onGiteaRun(t, func(t *testing.T, u *url.URL) {
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo3, is an org
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org
seed := user2.Email
if len(seed) == 0 {
@@ -72,7 +72,7 @@ func TestUserAvatar(t *testing.T) {
session.MakeRequest(t, req, http.StatusSeeOther)
- user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User) // owner of the repo3, is an org
+ user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) // owner of the repo3, is an org
req = NewRequest(t, "GET", user2.AvatarLinkWithSize(0))
_ = session.MakeRequest(t, req, http.StatusOK)
diff --git a/integrations/user_test.go b/integrations/user_test.go
index 33113369a749..b0c1cd42ebe3 100644
--- a/integrations/user_test.go
+++ b/integrations/user_test.go
@@ -229,16 +229,16 @@ func testExportUserGPGKeys(t *testing.T, user, expected string) {
func TestListStopWatches(t *testing.T) {
defer prepareTestEnv(t)()
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
session := loginUser(t, owner.Name)
req := NewRequestf(t, "GET", "/user/stopwatches")
resp := session.MakeRequest(t, req, http.StatusOK)
var apiWatches []*api.StopWatch
DecodeJSON(t, resp, &apiWatches)
- stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID}).(*issues_model.Stopwatch)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID}).(*issues_model.Issue)
+ stopwatch := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: owner.ID})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: stopwatch.IssueID})
if assert.Len(t, apiWatches, 1) {
assert.EqualValues(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix())
assert.EqualValues(t, issue.Index, apiWatches[0].IssueIndex)
diff --git a/integrations/webfinger_test.go b/integrations/webfinger_test.go
index 07bf58b509fe..3574941e4216 100644
--- a/integrations/webfinger_test.go
+++ b/integrations/webfinger_test.go
@@ -25,7 +25,7 @@ func TestWebfinger(t *testing.T) {
setting.Federation.Enabled = false
}()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
appURL, _ := url.Parse(setting.AppURL)
diff --git a/integrations/xss_test.go b/integrations/xss_test.go
index 1ce25e1bf5c3..d5ce94b0c6cc 100644
--- a/integrations/xss_test.go
+++ b/integrations/xss_test.go
@@ -16,7 +16,7 @@ import (
func TestXSSUserFullName(t *testing.T) {
defer prepareTestEnv(t)()
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
const fullName = `name & `
session := loginUser(t, user.Name)
diff --git a/main.go b/main.go
index ac60f85a6680..0e550f05ebca 100644
--- a/main.go
+++ b/main.go
@@ -171,9 +171,9 @@ func setAppHelpTemplates() {
}
func adjustHelpTemplate(originalTemplate string) string {
- overrided := ""
+ overridden := ""
if _, ok := os.LookupEnv("GITEA_CUSTOM"); ok {
- overrided = "(GITEA_CUSTOM)"
+ overridden = "(GITEA_CUSTOM)"
}
return fmt.Sprintf(`%s
@@ -183,7 +183,7 @@ DEFAULT CONFIGURATION:
AppPath: %s
AppWorkPath: %s
-`, originalTemplate, setting.CustomPath, overrided, setting.CustomConf, setting.AppPath, setting.AppWorkPath)
+`, originalTemplate, setting.CustomPath, overridden, setting.CustomConf, setting.AppPath, setting.AppWorkPath)
}
func formatBuiltWith() string {
diff --git a/models/action_test.go b/models/action_test.go
index 2d46bd3e80e1..5c61736a6150 100644
--- a/models/action_test.go
+++ b/models/action_test.go
@@ -19,16 +19,16 @@ import (
func TestAction_GetRepoPath(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
action := &Action{RepoID: repo.ID}
assert.Equal(t, path.Join(owner.Name, repo.Name), action.GetRepoPath())
}
func TestAction_GetRepoLink(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
action := &Action{RepoID: repo.ID}
setting.AppSubURL = "/suburl"
expected := path.Join(setting.AppSubURL, owner.Name, repo.Name)
@@ -38,7 +38,7 @@ func TestAction_GetRepoLink(t *testing.T) {
func TestGetFeeds(t *testing.T) {
// test with an individual user
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{
RequestedUser: user,
@@ -65,9 +65,9 @@ func TestGetFeeds(t *testing.T) {
func TestGetFeedsForRepos(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
- pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ privRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
+ pubRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
// private repo & no login
actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{
@@ -107,8 +107,8 @@ func TestGetFeedsForRepos(t *testing.T) {
func TestGetFeeds2(t *testing.T) {
// test with an organization user
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
actions, err := GetFeeds(db.DefaultContext, GetFeedsOptions{
RequestedUser: org,
@@ -214,7 +214,7 @@ func TestNotifyWatchers(t *testing.T) {
func TestGetFeedsCorrupted(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
unittest.AssertExistsAndLoadBean(t, &Action{
ID: 8,
RepoID: 1700,
diff --git a/models/asymkey/gpg_key_test.go b/models/asymkey/gpg_key_test.go
index 07bb77bdf468..2cee45d98f75 100644
--- a/models/asymkey/gpg_key_test.go
+++ b/models/asymkey/gpg_key_test.go
@@ -196,7 +196,7 @@ Unknown GPG key with good email
func TestCheckGPGUserEmail(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
testEmailWithUpperCaseLetters := `-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1
diff --git a/models/auth/oauth2.go b/models/auth/oauth2.go
index 5a58ec62b7d1..ad1d80e25a85 100644
--- a/models/auth/oauth2.go
+++ b/models/auth/oauth2.go
@@ -512,10 +512,14 @@ func GetActiveOAuth2ProviderSources() ([]*Source, error) {
func GetActiveOAuth2SourceByName(name string) (*Source, error) {
authSource := new(Source)
has, err := db.GetEngine(db.DefaultContext).Where("name = ? and type = ? and is_active = ?", name, OAuth2, true).Get(authSource)
- if !has || err != nil {
+ if err != nil {
return nil, err
}
+ if !has {
+ return nil, fmt.Errorf("oauth2 source not found, name: %q", name)
+ }
+
return authSource, nil
}
diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go
index cb8c4aeb6aa5..2a74f3999801 100644
--- a/models/auth/oauth2_test.go
+++ b/models/auth/oauth2_test.go
@@ -17,7 +17,7 @@ import (
func TestOAuth2Application_GenerateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1})
secret, err := app.GenerateClientSecret()
assert.NoError(t, err)
assert.True(t, len(secret) > 0)
@@ -26,7 +26,7 @@ func TestOAuth2Application_GenerateClientSecret(t *testing.T) {
func BenchmarkOAuth2Application_GenerateClientSecret(b *testing.B) {
assert.NoError(b, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1}).(*OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(b, &OAuth2Application{ID: 1})
for i := 0; i < b.N; i++ {
_, _ = app.GenerateClientSecret()
}
@@ -44,7 +44,7 @@ func TestOAuth2Application_ContainsRedirectURI(t *testing.T) {
func TestOAuth2Application_ValidateClientSecret(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1})
secret, err := app.GenerateClientSecret()
assert.NoError(t, err)
assert.True(t, app.ValidateClientSecret([]byte(secret)))
@@ -77,7 +77,7 @@ func TestOAuth2Application_TableName(t *testing.T) {
func TestOAuth2Application_GetGrantByUserID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1})
grant, err := app.GetGrantByUserID(db.DefaultContext, 1)
assert.NoError(t, err)
assert.Equal(t, int64(1), grant.UserID)
@@ -89,7 +89,7 @@ func TestOAuth2Application_GetGrantByUserID(t *testing.T) {
func TestOAuth2Application_CreateGrant(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1}).(*OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(t, &OAuth2Application{ID: 1})
grant, err := app.CreateGrant(db.DefaultContext, 2, "")
assert.NoError(t, err)
assert.NotNil(t, grant)
@@ -113,7 +113,7 @@ func TestGetOAuth2GrantByID(t *testing.T) {
func TestOAuth2Grant_IncreaseCounter(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1}).(*OAuth2Grant)
+ grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 1})
assert.NoError(t, grant.IncreaseCounter(db.DefaultContext))
assert.Equal(t, int64(2), grant.Counter)
unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Counter: 2})
@@ -121,7 +121,7 @@ func TestOAuth2Grant_IncreaseCounter(t *testing.T) {
func TestOAuth2Grant_ScopeContains(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"}).(*OAuth2Grant)
+ grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1, Scope: "openid profile"})
assert.True(t, grant.ScopeContains("openid"))
assert.True(t, grant.ScopeContains("profile"))
assert.False(t, grant.ScopeContains("profil"))
@@ -130,7 +130,7 @@ func TestOAuth2Grant_ScopeContains(t *testing.T) {
func TestOAuth2Grant_GenerateNewAuthorizationCode(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1}).(*OAuth2Grant)
+ grant := unittest.AssertExistsAndLoadBean(t, &OAuth2Grant{ID: 1})
code, err := grant.GenerateNewAuthorizationCode(db.DefaultContext, "https://example2.com/callback", "CjvyTLSdR47G5zYenDA-eDWW4lRrO8yvjcWwbD_deOg", "S256")
assert.NoError(t, err)
assert.NotNil(t, code)
@@ -224,7 +224,7 @@ func TestOAuth2AuthorizationCode_GenerateRedirectURI(t *testing.T) {
func TestOAuth2AuthorizationCode_Invalidate(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"}).(*OAuth2AuthorizationCode)
+ code := unittest.AssertExistsAndLoadBean(t, &OAuth2AuthorizationCode{Code: "authcode"})
assert.NoError(t, code.Invalidate(db.DefaultContext))
unittest.AssertNotExistsBean(t, &OAuth2AuthorizationCode{Code: "authcode"})
}
diff --git a/models/auth/webauthn_test.go b/models/auth/webauthn_test.go
index cc39691ce2d3..edbb7ecd5b4e 100644
--- a/models/auth/webauthn_test.go
+++ b/models/auth/webauthn_test.go
@@ -40,7 +40,7 @@ func TestWebAuthnCredential_TableName(t *testing.T) {
func TestWebAuthnCredential_UpdateSignCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}).(*WebAuthnCredential)
+ cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1})
cred.SignCount = 1
assert.NoError(t, cred.UpdateSignCount())
unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 1})
@@ -48,7 +48,7 @@ func TestWebAuthnCredential_UpdateSignCount(t *testing.T) {
func TestWebAuthnCredential_UpdateLargeCounter(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1}).(*WebAuthnCredential)
+ cred := unittest.AssertExistsAndLoadBean(t, &WebAuthnCredential{ID: 1})
cred.SignCount = 0xffffffff
assert.NoError(t, cred.UpdateSignCount())
unittest.AssertExistsIf(t, true, &WebAuthnCredential{ID: 1, SignCount: 0xffffffff})
diff --git a/models/db/iterate.go b/models/db/iterate.go
new file mode 100644
index 000000000000..3d4fa06eeb96
--- /dev/null
+++ b/models/db/iterate.go
@@ -0,0 +1,34 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package db
+
+import (
+ "context"
+
+ "code.gitea.io/gitea/modules/setting"
+)
+
+// IterateObjects iterate all the Bean object
+func IterateObjects[Object any](ctx context.Context, f func(repo *Object) error) error {
+ var start int
+ batchSize := setting.Database.IterateBufferSize
+ sess := GetEngine(ctx)
+ for {
+ repos := make([]*Object, 0, batchSize)
+ if err := sess.Limit(batchSize, start).Find(&repos); err != nil {
+ return err
+ }
+ if len(repos) == 0 {
+ return nil
+ }
+ start += len(repos)
+
+ for _, repo := range repos {
+ if err := f(repo); err != nil {
+ return err
+ }
+ }
+ }
+}
diff --git a/models/git/branches_test.go b/models/git/branches_test.go
index 8102d28d484b..58c4ad027be1 100644
--- a/models/git/branches_test.go
+++ b/models/git/branches_test.go
@@ -18,8 +18,8 @@ import (
func TestAddDeletedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})
assert.Error(t, git_model.AddDeletedBranch(repo.ID, firstBranch.Name, firstBranch.Commit, firstBranch.DeletedByID))
assert.NoError(t, git_model.AddDeletedBranch(repo.ID, "test", "5655464564554545466464656", int64(1)))
@@ -27,7 +27,7 @@ func TestAddDeletedBranch(t *testing.T) {
func TestGetDeletedBranches(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
branches, err := git_model.GetDeletedBranches(repo.ID)
assert.NoError(t, err)
@@ -36,7 +36,7 @@ func TestGetDeletedBranches(t *testing.T) {
func TestGetDeletedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
+ firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})
assert.NotNil(t, getDeletedBranch(t, firstBranch))
}
@@ -44,8 +44,8 @@ func TestGetDeletedBranch(t *testing.T) {
func TestDeletedBranchLoadUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
- secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2}).(*git_model.DeletedBranch)
+ firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})
+ secondBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 2})
branch := getDeletedBranch(t, firstBranch)
assert.Nil(t, branch.DeletedBy)
@@ -62,9 +62,9 @@ func TestDeletedBranchLoadUser(t *testing.T) {
func TestRemoveDeletedBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
- firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1}).(*git_model.DeletedBranch)
+ firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.DeletedBranch{ID: 1})
err := git_model.RemoveDeletedBranchByID(repo.ID, 1)
assert.NoError(t, err)
@@ -73,7 +73,7 @@ func TestRemoveDeletedBranch(t *testing.T) {
}
func getDeletedBranch(t *testing.T, branch *git_model.DeletedBranch) *git_model.DeletedBranch {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
deletedBranch, err := git_model.GetDeletedBranchByID(repo.ID, branch.ID)
assert.NoError(t, err)
@@ -99,7 +99,7 @@ func TestFindRenamedBranch(t *testing.T) {
func TestRenameBranch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
_isDefault := false
ctx, committer, err := db.TxContext()
@@ -117,16 +117,16 @@ func TestRenameBranch(t *testing.T) {
}))
assert.Equal(t, true, _isDefault)
- repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.Equal(t, "main", repo1.DefaultBranch)
- pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest) // merged
+ pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}) // merged
assert.Equal(t, "master", pull.BaseBranch)
- pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest) // open
+ pull = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}) // open
assert.Equal(t, "main", pull.BaseBranch)
- renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2}).(*git_model.RenamedBranch)
+ renamedBranch := unittest.AssertExistsAndLoadBean(t, &git_model.RenamedBranch{ID: 2})
assert.Equal(t, "master", renamedBranch.From)
assert.Equal(t, "main", renamedBranch.To)
assert.Equal(t, int64(1), renamedBranch.RepoID)
@@ -143,7 +143,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
// Get deletedBranch with ID of 1 on repo with ID 2.
// This should return a nil branch as this deleted branch
// is actually on repo with ID 1.
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
deletedBranch, err := git_model.GetDeletedBranchByID(repo2.ID, 1)
@@ -153,7 +153,7 @@ func TestOnlyGetDeletedBranchOnCorrectRepo(t *testing.T) {
// Now get the deletedBranch with ID of 1 on repo with ID 1.
// This should return the deletedBranch.
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
deletedBranch, err = git_model.GetDeletedBranchByID(repo1.ID, 1)
diff --git a/models/git/commit_status_test.go b/models/git/commit_status_test.go
index 991929743006..7b81b1549c22 100644
--- a/models/git/commit_status_test.go
+++ b/models/git/commit_status_test.go
@@ -19,7 +19,7 @@ import (
func TestGetCommitStatuses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
sha1 := "1234123412341234123412341234123412341234"
diff --git a/models/git/lfs.go b/models/git/lfs.go
index ec963cf59358..179da3120ae1 100644
--- a/models/git/lfs.go
+++ b/models/git/lfs.go
@@ -278,29 +278,6 @@ func LFSAutoAssociate(metas []*LFSMetaObject, user *user_model.User, repoID int6
return committer.Commit()
}
-// IterateLFS iterates lfs object
-func IterateLFS(f func(mo *LFSMetaObject) error) error {
- var start int
- const batchSize = 100
- e := db.GetEngine(db.DefaultContext)
- for {
- mos := make([]*LFSMetaObject, 0, batchSize)
- if err := e.Limit(batchSize, start).Find(&mos); err != nil {
- return err
- }
- if len(mos) == 0 {
- return nil
- }
- start += len(mos)
-
- for _, mo := range mos {
- if err := f(mo); err != nil {
- return err
- }
- }
- }
-}
-
// CopyLFS copies LFS data from one repo to another
func CopyLFS(ctx context.Context, newRepo, oldRepo *repo_model.Repository) error {
var lfsObjects []*LFSMetaObject
diff --git a/models/issues/assignees_test.go b/models/issues/assignees_test.go
index 37d966f140f7..291bb673da84 100644
--- a/models/issues/assignees_test.go
+++ b/models/issues/assignees_test.go
@@ -68,8 +68,8 @@ func TestUpdateAssignee(t *testing.T) {
func TestMakeIDsFromAPIAssigneesToAdd(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ _ = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
IDs, err := issues_model.MakeIDsFromAPIAssigneesToAdd("", []string{""})
assert.NoError(t, err)
diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go
index 06b0b85e3cff..f12da0177f86 100644
--- a/models/issues/comment_test.go
+++ b/models/issues/comment_test.go
@@ -20,9 +20,9 @@ import (
func TestCreateComment(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
now := time.Now().Unix()
comment, err := issues_model.CreateComment(&issues_model.CreateCommentOptions{
@@ -42,15 +42,15 @@ func TestCreateComment(t *testing.T) {
unittest.AssertInt64InRange(t, now, then, int64(comment.CreatedUnix))
unittest.AssertExistsAndLoadBean(t, comment) // assert actually added to DB
- updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue)
+ updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix))
}
func TestFetchCodeComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
res, err := issues_model.FetchCodeComments(db.DefaultContext, issue, user)
assert.NoError(t, err)
assert.Contains(t, res, "README.md")
@@ -58,7 +58,7 @@ func TestFetchCodeComments(t *testing.T) {
assert.Len(t, res["README.md"][4], 1)
assert.Equal(t, int64(4), res["README.md"][4][0].ID)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
res, err = issues_model.FetchCodeComments(db.DefaultContext, issue, user2)
assert.NoError(t, err)
assert.Len(t, res, 1)
diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go
index 6b978f9ae602..f2cfca9bc0af 100644
--- a/models/issues/issue_list_test.go
+++ b/models/issues/issue_list_test.go
@@ -18,9 +18,9 @@ func TestIssueList_LoadRepositories(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
issueList := issues_model.IssueList{
- unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue),
- unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue),
- unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}),
}
repos, err := issueList.LoadRepositories()
@@ -35,8 +35,8 @@ func TestIssueList_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
setting.Service.EnableTimetracking = true
issueList := issues_model.IssueList{
- unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue),
- unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}),
}
assert.NoError(t, issueList.LoadAttributes())
diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go
index 019e578da874..bef5d03e8afa 100644
--- a/models/issues/issue_test.go
+++ b/models/issues/issue_test.go
@@ -29,13 +29,13 @@ func TestIssue_ReplaceLabels(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(issueID int64, labelIDs []int64) {
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID}).(*repo_model.Repository)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: issue.RepoID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
labels := make([]*issues_model.Label, len(labelIDs))
for i, labelID := range labelIDs {
- labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID}).(*issues_model.Label)
+ labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID, RepoID: repo.ID})
}
assert.NoError(t, issues_model.ReplaceIssueLabels(issue, labels, doer))
unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issueID}, len(labelIDs))
@@ -59,7 +59,7 @@ func Test_GetIssueIDsByRepoID(t *testing.T) {
func TestIssueAPIURL(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
err := issue.LoadAttributes(db.DefaultContext)
assert.NoError(t, err)
@@ -117,8 +117,8 @@ func TestIssue_ClearLabels(t *testing.T) {
}
for _, test := range tests {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
assert.NoError(t, issues_model.ClearIssueLabels(issue, doer))
unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: test.issueID})
}
@@ -126,7 +126,7 @@ func TestIssue_ClearLabels(t *testing.T) {
func TestUpdateIssueCols(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{})
const newTitle = "New Title for unit test"
issue.Title = newTitle
@@ -138,7 +138,7 @@ func TestUpdateIssueCols(t *testing.T) {
assert.NoError(t, issues_model.UpdateIssueCols(db.DefaultContext, issue, "name"))
then := time.Now().Unix()
- updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}).(*issues_model.Issue)
+ updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID})
assert.EqualValues(t, newTitle, updatedIssue.Title)
assert.EqualValues(t, prevContent, updatedIssue.Content)
unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix))
@@ -291,8 +291,8 @@ func TestGetUserIssueStats(t *testing.T) {
{
issues_model.UserIssueStatsOptions{
UserID: 2,
- Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization),
- Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}).(*organization.Team),
+ Org: unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}),
+ Team: unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 7}),
FilterMode: issues_model.FilterModeAll,
},
issues_model.IssueStats{
@@ -347,7 +347,7 @@ func TestIssue_SearchIssueIDsByKeyword(t *testing.T) {
func TestGetRepoIDsForIssuesOptions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
for _, test := range []struct {
Opts issues_model.IssuesOptions
ExpectedRepoIDs []int64
@@ -378,8 +378,8 @@ func TestGetRepoIDsForIssuesOptions(t *testing.T) {
func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *issues_model.Issue {
var newIssue issues_model.Issue
t.Run(title, func(t *testing.T) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
issue := issues_model.Issue{
RepoID: repo.ID,
@@ -420,10 +420,10 @@ func TestIssue_ResolveMentions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(owner, repo, doer string, mentions []string, expected []int64) {
- o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner}).(*user_model.User)
- r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo}).(*repo_model.Repository)
+ o := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: owner})
+ r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: o.ID, LowerName: repo})
issue := &issues_model.Issue{RepoID: r.ID}
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer}).(*user_model.User)
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: doer})
resolved, err := issues_model.ResolveIssueMentionsByVisibility(db.DefaultContext, issue, d, mentions)
assert.NoError(t, err)
ids := make([]int64, len(resolved))
@@ -504,7 +504,7 @@ func TestCorrectIssueStats(t *testing.T) {
func TestIssueForeignReference(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 4})
assert.NotEqualValues(t, issue.Index, issue.ID) // make sure they are different to avoid false positive
// it is fine for an issue to not have a foreign reference
@@ -537,7 +537,7 @@ func TestIssueForeignReference(t *testing.T) {
func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
miles := issues_model.MilestoneList{
- unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}),
}
assert.NoError(t, miles.LoadTotalTrackedTimes())
@@ -547,7 +547,7 @@ func TestMilestoneList_LoadTotalTrackedTimes(t *testing.T) {
func TestLoadTotalTrackedTime(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
+ milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
assert.NoError(t, milestone.LoadTotalTrackedTime())
diff --git a/models/issues/issue_user_test.go b/models/issues/issue_user_test.go
index 33e9f98ecc43..7dd84ed68cdf 100644
--- a/models/issues/issue_user_test.go
+++ b/models/issues/issue_user_test.go
@@ -18,7 +18,7 @@ import (
func Test_NewIssueUsers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
newIssue := &issues_model.Issue{
RepoID: repo.ID,
PosterID: 4,
@@ -39,7 +39,7 @@ func Test_NewIssueUsers(t *testing.T) {
func TestUpdateIssueUserByRead(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
assert.NoError(t, issues_model.UpdateIssueUserByRead(4, issue.ID))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueUser{IssueID: issue.ID, UID: 4}, "is_read=1")
@@ -52,7 +52,7 @@ func TestUpdateIssueUserByRead(t *testing.T) {
func TestUpdateIssueUsersByMentions(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
uids := []int64{2, 5}
assert.NoError(t, issues_model.UpdateIssueUsersByMentions(db.DefaultContext, issue.ID, uids))
diff --git a/models/issues/issue_watch_test.go b/models/issues/issue_watch_test.go
index c6b6416d9b32..7aaf9f7f5da5 100644
--- a/models/issues/issue_watch_test.go
+++ b/models/issues/issue_watch_test.go
@@ -18,11 +18,11 @@ func TestCreateOrUpdateIssueWatch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(3, 1, true))
- iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1}).(*issues_model.IssueWatch)
+ iw := unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 3, IssueID: 1})
assert.True(t, iw.IsWatching)
assert.NoError(t, issues_model.CreateOrUpdateIssueWatch(1, 1, false))
- iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1}).(*issues_model.IssueWatch)
+ iw = unittest.AssertExistsAndLoadBean(t, &issues_model.IssueWatch{UserID: 1, IssueID: 1})
assert.False(t, iw.IsWatching)
}
diff --git a/models/issues/issue_xref_test.go b/models/issues/issue_xref_test.go
index 6bb19d5328d5..af1c8bc68506 100644
--- a/models/issues/issue_xref_test.go
+++ b/models/issues/issue_xref_test.go
@@ -27,7 +27,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
// PR to close issue #1
content := fmt.Sprintf("content2, closes #%d", itarget.Index)
pr := testCreateIssue(t, 1, 2, "title2", content, true)
- ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0}).(*issues_model.Comment)
+ ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypePullRef, ref.Type)
assert.Equal(t, pr.RepoID, ref.RefRepoID)
assert.True(t, ref.RefIsPull)
@@ -36,7 +36,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
// Comment on PR to reopen issue #1
content = fmt.Sprintf("content2, reopens #%d", itarget.Index)
c := testCreateComment(t, 1, 2, pr.ID, content)
- ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID}).(*issues_model.Comment)
+ ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: pr.ID, RefCommentID: c.ID})
assert.Equal(t, issues_model.CommentTypeCommentRef, ref.Type)
assert.Equal(t, pr.RepoID, ref.RefRepoID)
assert.True(t, ref.RefIsPull)
@@ -45,7 +45,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
// Issue mentioning issue #1
content = fmt.Sprintf("content3, mentions #%d", itarget.Index)
i := testCreateIssue(t, 1, 2, "title3", content, false)
- ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment)
+ ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type)
assert.Equal(t, pr.RepoID, ref.RefRepoID)
assert.False(t, ref.RefIsPull)
@@ -57,7 +57,7 @@ func TestXRef_AddCrossReferences(t *testing.T) {
// Cross-reference to issue #4 by admin
content = fmt.Sprintf("content5, mentions user3/repo3#%d", itarget.Index)
i = testCreateIssue(t, 2, 1, "title5", content, false)
- ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment)
+ ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type)
assert.Equal(t, i.RepoID, ref.RefRepoID)
assert.False(t, ref.RefIsPull)
@@ -78,15 +78,15 @@ func TestXRef_NeuterCrossReferences(t *testing.T) {
// Issue mentioning issue #1
title := fmt.Sprintf("title2, mentions #%d", itarget.Index)
i := testCreateIssue(t, 1, 2, title, "content2", false)
- ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment)
+ ref := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type)
assert.Equal(t, references.XRefActionNone, ref.RefAction)
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
i.Title = "title2, no mentions"
assert.NoError(t, issues_model.ChangeIssueTitle(i, d, title))
- ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0}).(*issues_model.Comment)
+ ref = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: itarget.ID, RefIssueID: i.ID, RefCommentID: 0})
assert.Equal(t, issues_model.CommentTypeIssueRef, ref.Type)
assert.Equal(t, references.XRefActionNeutered, ref.RefAction)
}
@@ -94,7 +94,7 @@ func TestXRef_NeuterCrossReferences(t *testing.T) {
func TestXRef_ResolveCrossReferences(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
i1 := testCreateIssue(t, 1, 2, "title1", "content1", false)
i2 := testCreateIssue(t, 1, 2, "title2", "content2", false)
@@ -103,10 +103,10 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
assert.NoError(t, err)
pr := testCreatePR(t, 1, 2, "titlepr", fmt.Sprintf("closes #%d", i1.Index))
- rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0}).(*issues_model.Comment)
+ rp := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i1.ID, RefIssueID: pr.Issue.ID, RefCommentID: 0})
c1 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i2.Index))
- r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID}).(*issues_model.Comment)
+ r1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i2.ID, RefIssueID: pr.Issue.ID, RefCommentID: c1.ID})
// Must be ignored
c2 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("mentions #%d", i2.Index))
@@ -117,7 +117,7 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c3.ID})
c4 := testCreateComment(t, 1, 2, pr.Issue.ID, fmt.Sprintf("closes #%d", i3.Index))
- r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID}).(*issues_model.Comment)
+ r4 := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{IssueID: i3.ID, RefIssueID: pr.Issue.ID, RefCommentID: c4.ID})
refs, err := pr.ResolveCrossReferences(db.DefaultContext)
assert.NoError(t, err)
@@ -128,8 +128,8 @@ func TestXRef_ResolveCrossReferences(t *testing.T) {
}
func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispull bool) *issues_model.Issue {
- r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
+ r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo})
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
idx, err := db.GetNextResourceIndex("issue_index", r.ID)
assert.NoError(t, err)
@@ -159,8 +159,8 @@ func testCreateIssue(t *testing.T, repo, doer int64, title, content string, ispu
}
func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues_model.PullRequest {
- r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo}).(*repo_model.Repository)
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
+ r := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo})
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
i := &issues_model.Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
pr := &issues_model.PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: issues_model.PullRequestStatusMergeable}
assert.NoError(t, issues_model.NewPullRequest(db.DefaultContext, r, i, nil, nil, pr))
@@ -169,8 +169,8 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *issues
}
func testCreateComment(t *testing.T, repo, doer, issue int64, content string) *issues_model.Comment {
- d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
- i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue}).(*issues_model.Issue)
+ d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer})
+ i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue})
c := &issues_model.Comment{Type: issues_model.CommentTypeComment, PosterID: doer, Poster: d, IssueID: issue, Issue: i, Content: content}
ctx, committer, err := db.TxContext()
diff --git a/models/issues/label_test.go b/models/issues/label_test.go
index 33f114b5fe09..9ad6fd427b92 100644
--- a/models/issues/label_test.go
+++ b/models/issues/label_test.go
@@ -21,17 +21,17 @@ import (
func TestLabel_CalOpenIssues(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
label.CalOpenIssues()
assert.EqualValues(t, 2, label.NumOpenIssues)
}
func TestLabel_ForegroundColor(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
assert.Equal(t, template.CSS("#000"), label.ForegroundColor())
- label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label)
+ label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
assert.Equal(t, template.CSS("#fff"), label.ForegroundColor())
}
@@ -260,7 +260,7 @@ func TestGetLabelsByIssueID(t *testing.T) {
func TestUpdateLabel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
// make sure update wont overwrite it
update := &issues_model.Label{
ID: label.ID,
@@ -271,7 +271,7 @@ func TestUpdateLabel(t *testing.T) {
label.Color = update.Color
label.Name = update.Name
assert.NoError(t, issues_model.UpdateLabel(update))
- newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ newLabel := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
assert.EqualValues(t, label.ID, newLabel.ID)
assert.EqualValues(t, label.Color, newLabel.Color)
assert.EqualValues(t, label.Name, newLabel.Name)
@@ -281,7 +281,7 @@ func TestUpdateLabel(t *testing.T) {
func TestDeleteLabel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
assert.NoError(t, issues_model.DeleteLabel(label.RepoID, label.ID))
unittest.AssertNotExistsBean(t, &issues_model.Label{ID: label.ID, RepoID: label.RepoID})
@@ -301,9 +301,9 @@ func TestHasIssueLabel(t *testing.T) {
func TestNewIssueLabel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// add new IssueLabel
prevNumIssues := label.NumIssues
@@ -316,7 +316,7 @@ func TestNewIssueLabel(t *testing.T) {
LabelID: label.ID,
Content: "1",
})
- label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label)
+ label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
assert.EqualValues(t, prevNumIssues+1, label.NumIssues)
// re-add existing IssueLabel
@@ -326,10 +326,10 @@ func TestNewIssueLabel(t *testing.T) {
func TestNewIssueLabels(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
- label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5}).(*issues_model.Issue)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ label1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ label2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 5})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, issues_model.NewIssueLabels(issue, []*issues_model.Label{label1, label2}, doer))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
@@ -341,10 +341,10 @@ func TestNewIssueLabels(t *testing.T) {
Content: "1",
})
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID})
- label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
+ label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
assert.EqualValues(t, 3, label1.NumIssues)
assert.EqualValues(t, 1, label1.NumClosedIssues)
- label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}).(*issues_model.Label)
+ label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2})
assert.EqualValues(t, 1, label2.NumIssues)
assert.EqualValues(t, 1, label2.NumClosedIssues)
@@ -357,9 +357,9 @@ func TestNewIssueLabels(t *testing.T) {
func TestDeleteIssueLabel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(labelID, issueID, doerID int64) {
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label)
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID}).(*issues_model.Issue)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID}).(*user_model.User)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issueID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doerID})
expectedNumIssues := label.NumIssues
expectedNumClosedIssues := label.NumClosedIssues
@@ -383,7 +383,7 @@ func TestDeleteIssueLabel(t *testing.T) {
IssueID: issueID,
LabelID: labelID,
}, `content=""`)
- label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label)
+ label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
assert.EqualValues(t, expectedNumIssues, label.NumIssues)
assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues)
}
diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go
index a6fbf9c23b53..f04a2b2b3bef 100644
--- a/models/issues/milestone_test.go
+++ b/models/issues/milestone_test.go
@@ -40,7 +40,7 @@ func TestGetMilestoneByRepoID(t *testing.T) {
func TestGetMilestonesByRepoID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64, state api.StateType) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{
RepoID: repo.ID,
State: state,
@@ -88,7 +88,7 @@ func TestGetMilestonesByRepoID(t *testing.T) {
func TestGetMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
test := func(sortType string, sortCond func(*issues_model.Milestone) int) {
for _, page := range []int{0, 1} {
milestones, _, err := issues_model.GetMilestones(issues_model.GetMilestonesOption{
@@ -150,7 +150,7 @@ func TestGetMilestones(t *testing.T) {
func TestCountRepoMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{
RepoID: repoID,
State: api.StateAll,
@@ -173,7 +173,7 @@ func TestCountRepoMilestones(t *testing.T) {
func TestCountRepoClosedMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
count, err := issues_model.CountMilestones(db.DefaultContext, issues_model.GetMilestonesOption{
RepoID: repoID,
State: api.StateClosed,
@@ -196,7 +196,7 @@ func TestCountRepoClosedMilestones(t *testing.T) {
func TestCountMilestonesByRepoIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
milestonesCount := func(repoID int64) (int, int) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
return repo.NumOpenMilestones, repo.NumClosedMilestones
}
repo1OpenCount, repo1ClosedCount := milestonesCount(1)
@@ -215,8 +215,8 @@ func TestCountMilestonesByRepoIDs(t *testing.T) {
func TestGetMilestonesByRepoIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
test := func(sortType string, sortCond func(*issues_model.Milestone) int) {
for _, page := range []int{0, 1} {
openMilestones, err := issues_model.GetMilestonesByRepoIDs([]int64{repo1.ID, repo2.ID}, page, false, sortType)
@@ -262,7 +262,7 @@ func TestGetMilestonesStats(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
stats, err := issues_model.GetMilestonesStatsByRepoCond(builder.And(builder.Eq{"repo_id": repoID}))
assert.NoError(t, err)
assert.EqualValues(t, repo.NumMilestones-repo.NumClosedMilestones, stats.OpenCount)
@@ -277,8 +277,8 @@ func TestGetMilestonesStats(t *testing.T) {
assert.EqualValues(t, 0, stats.OpenCount)
assert.EqualValues(t, 0, stats.ClosedCount)
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
milestoneStats, err := issues_model.GetMilestonesStatsByRepoCond(builder.In("repo_id", []int64{repo1.ID, repo2.ID}))
assert.NoError(t, err)
@@ -301,7 +301,7 @@ func TestNewMilestone(t *testing.T) {
func TestChangeMilestoneStatus(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
+ milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
assert.NoError(t, issues_model.ChangeMilestoneStatus(milestone, true))
unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}, "is_closed=1")
@@ -324,11 +324,11 @@ func TestDeleteMilestoneByRepoID(t *testing.T) {
func TestUpdateMilestone(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
+ milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
milestone.Name = " newMilestoneName "
milestone.Content = "newMilestoneContent"
assert.NoError(t, issues_model.UpdateMilestone(milestone, milestone.IsClosed))
- milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
+ milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
assert.EqualValues(t, "newMilestoneName", milestone.Name)
unittest.CheckConsistencyFor(t, &issues_model.Milestone{})
}
@@ -336,7 +336,7 @@ func TestUpdateMilestone(t *testing.T) {
func TestUpdateMilestoneCounters(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{MilestoneID: 1},
- "is_closed=0").(*issues_model.Issue)
+ "is_closed=0")
issue.IsClosed = true
issue.ClosedUnix = timeutil.TimeStampNow()
diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go
index 0d1991383d31..fb46e3071e39 100644
--- a/models/issues/pull_test.go
+++ b/models/issues/pull_test.go
@@ -16,7 +16,7 @@ import (
func TestPullRequest_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadAttributes())
assert.NotNil(t, pr.Merger)
assert.Equal(t, pr.MergerID, pr.Merger.ID)
@@ -24,7 +24,7 @@ func TestPullRequest_LoadAttributes(t *testing.T) {
func TestPullRequest_LoadIssue(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadIssue())
assert.NotNil(t, pr.Issue)
assert.Equal(t, int64(2), pr.Issue.ID)
@@ -35,7 +35,7 @@ func TestPullRequest_LoadIssue(t *testing.T) {
func TestPullRequest_LoadBaseRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadBaseRepo())
assert.NotNil(t, pr.BaseRepo)
assert.Equal(t, pr.BaseRepoID, pr.BaseRepo.ID)
@@ -46,7 +46,7 @@ func TestPullRequest_LoadBaseRepo(t *testing.T) {
func TestPullRequest_LoadHeadRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadHeadRepo())
assert.NotNil(t, pr.HeadRepo)
assert.Equal(t, pr.HeadRepoID, pr.HeadRepo.ID)
@@ -180,12 +180,12 @@ func TestGetPullRequestByIssueID(t *testing.T) {
func TestPullRequest_Update(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
pr.BaseBranch = "baseBranch"
pr.HeadBranch = "headBranch"
pr.Update()
- pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}).(*issues_model.PullRequest)
+ pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID})
assert.Equal(t, "baseBranch", pr.BaseBranch)
assert.Equal(t, "headBranch", pr.HeadBranch)
unittest.CheckConsistencyFor(t, pr)
@@ -200,7 +200,7 @@ func TestPullRequest_UpdateCols(t *testing.T) {
}
assert.NoError(t, pr.UpdateCols("head_branch"))
- pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.Equal(t, "master", pr.BaseBranch)
assert.Equal(t, "headBranch", pr.HeadBranch)
unittest.CheckConsistencyFor(t, pr)
@@ -210,8 +210,8 @@ func TestPullRequestList_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
prs := []*issues_model.PullRequest{
- unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest),
- unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}),
+ unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}),
}
assert.NoError(t, issues_model.PullRequestList(prs).LoadAttributes())
for _, pr := range prs {
@@ -227,7 +227,7 @@ func TestPullRequestList_LoadAttributes(t *testing.T) {
func TestPullRequest_IsWorkInProgress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
pr.LoadIssue()
assert.False(t, pr.IsWorkInProgress())
@@ -242,7 +242,7 @@ func TestPullRequest_IsWorkInProgress(t *testing.T) {
func TestPullRequest_GetWorkInProgressPrefixWorkInProgress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
pr.LoadIssue()
assert.Empty(t, pr.GetWorkInProgressPrefix())
diff --git a/models/issues/reaction_test.go b/models/issues/reaction_test.go
index ee1b6687a264..835a667619cb 100644
--- a/models/issues/reaction_test.go
+++ b/models/issues/reaction_test.go
@@ -32,7 +32,7 @@ func addReaction(t *testing.T, doerID, issueID, commentID int64, content string)
func TestIssueAddReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var issue1ID int64 = 1
@@ -44,7 +44,7 @@ func TestIssueAddReaction(t *testing.T) {
func TestIssueAddDuplicateReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var issue1ID int64 = 1
@@ -58,14 +58,14 @@ func TestIssueAddDuplicateReaction(t *testing.T) {
assert.Error(t, err)
assert.Equal(t, issues_model.ErrReactionAlreadyExist{Reaction: "heart"}, err)
- existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID}).(*issues_model.Reaction)
+ existingR := unittest.AssertExistsAndLoadBean(t, &issues_model.Reaction{Type: "heart", UserID: user1.ID, IssueID: issue1ID})
assert.Equal(t, existingR.ID, reaction.ID)
}
func TestIssueDeleteReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var issue1ID int64 = 1
@@ -82,14 +82,14 @@ func TestIssueReactionCount(t *testing.T) {
setting.UI.ReactionMaxUserNum = 2
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
ghost := user_model.NewGhostUser()
var issueID int64 = 2
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
addReaction(t, user1.ID, issueID, 0, "heart")
addReaction(t, user2.ID, issueID, 0, "heart")
@@ -122,7 +122,7 @@ func TestIssueReactionCount(t *testing.T) {
func TestIssueCommentAddReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var issue1ID int64 = 1
var comment1ID int64 = 1
@@ -135,10 +135,10 @@ func TestIssueCommentAddReaction(t *testing.T) {
func TestIssueCommentDeleteReaction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
var issue1ID int64 = 1
var comment1ID int64 = 1
@@ -163,7 +163,7 @@ func TestIssueCommentDeleteReaction(t *testing.T) {
func TestIssueCommentReactionCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var issue1ID int64 = 1
var comment1ID int64 = 1
diff --git a/models/issues/review_test.go b/models/issues/review_test.go
index 3506604b46db..46d1cc777b65 100644
--- a/models/issues/review_test.go
+++ b/models/issues/review_test.go
@@ -29,22 +29,22 @@ func TestGetReviewByID(t *testing.T) {
func TestReview_LoadAttributes(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1}).(*issues_model.Review)
+ review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 1})
assert.NoError(t, review.LoadAttributes(db.DefaultContext))
assert.NotNil(t, review.Issue)
assert.NotNil(t, review.Reviewer)
- invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2}).(*issues_model.Review)
+ invalidReview1 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 2})
assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext))
- invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3}).(*issues_model.Review)
+ invalidReview2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 3})
assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext))
}
func TestReview_LoadCodeComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4}).(*issues_model.Review)
+ review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 4})
assert.NoError(t, review.LoadAttributes(db.DefaultContext))
assert.NoError(t, review.LoadCodeComments(db.DefaultContext))
assert.Len(t, review.CodeComments, 1)
@@ -74,8 +74,8 @@ func TestFindReviews(t *testing.T) {
func TestGetCurrentReview(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
review, err := issues_model.GetCurrentReview(db.DefaultContext, user, issue)
assert.NoError(t, err)
@@ -83,7 +83,7 @@ func TestGetCurrentReview(t *testing.T) {
assert.Equal(t, issues_model.ReviewTypePending, review.Type)
assert.Equal(t, "Pending Review", review.Content)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 7})
review2, err := issues_model.GetCurrentReview(db.DefaultContext, user2, issue)
assert.Error(t, err)
assert.True(t, issues_model.IsErrReviewNotExist(err))
@@ -93,8 +93,8 @@ func TestGetCurrentReview(t *testing.T) {
func TestCreateReview(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
review, err := issues_model.CreateReview(db.DefaultContext, issues_model.CreateReviewOptions{
Content: "New Review",
@@ -110,10 +110,10 @@ func TestCreateReview(t *testing.T) {
func TestGetReviewersByIssueID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3}).(*issues_model.Issue)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 3})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
expectedReviews := []*issues_model.Review{}
expectedReviews = append(expectedReviews,
@@ -150,43 +150,43 @@ func TestGetReviewersByIssueID(t *testing.T) {
func TestDismissReview(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
- approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8}).(*issues_model.Review)
+ rejectReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
+ approveReviewExample := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 8})
assert.False(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
assert.NoError(t, issues_model.DismissReview(rejectReviewExample, true))
- rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
+ rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.NoError(t, issues_model.DismissReview(requestReviewExample, true))
- rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
+ rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
assert.NoError(t, issues_model.DismissReview(requestReviewExample, true))
- rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
+ rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
assert.NoError(t, issues_model.DismissReview(requestReviewExample, false))
- rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
+ rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
assert.NoError(t, issues_model.DismissReview(requestReviewExample, false))
- rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9}).(*issues_model.Review)
- requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11}).(*issues_model.Review)
+ rejectReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 9})
+ requestReviewExample = unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 11})
assert.True(t, rejectReviewExample.Dismissed)
assert.False(t, requestReviewExample.Dismissed)
assert.False(t, approveReviewExample.Dismissed)
diff --git a/models/issues/stopwatch_test.go b/models/issues/stopwatch_test.go
index c0573964d5c4..a5e33f1cf6e2 100644
--- a/models/issues/stopwatch_test.go
+++ b/models/issues/stopwatch_test.go
@@ -70,7 +70,7 @@ func TestCreateOrStopIssueStopwatch(t *testing.T) {
assert.NoError(t, err)
assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user3, issue1))
- sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1}).(*issues_model.Stopwatch)
+ sw := unittest.AssertExistsAndLoadBean(t, &issues_model.Stopwatch{UserID: 3, IssueID: 1})
assert.LessOrEqual(t, sw.CreatedUnix, timeutil.TimeStampNow())
assert.NoError(t, issues_model.CreateOrStopIssueStopwatch(user2, issue2))
diff --git a/models/issues/tracked_time_test.go b/models/issues/tracked_time_test.go
index 787ba9b701e1..ba8b242d9991 100644
--- a/models/issues/tracked_time_test.go
+++ b/models/issues/tracked_time_test.go
@@ -32,10 +32,10 @@ func TestAddTime(t *testing.T) {
assert.Equal(t, int64(1), trackedTime.IssueID)
assert.Equal(t, int64(3661), trackedTime.Time)
- tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1}).(*issues_model.TrackedTime)
+ tt := unittest.AssertExistsAndLoadBean(t, &issues_model.TrackedTime{UserID: 3, IssueID: 1})
assert.Equal(t, int64(3661), tt.Time)
- comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1}).(*issues_model.Comment)
+ comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{Type: issues_model.CommentTypeAddTimeManual, PosterID: 3, IssueID: 1})
assert.Equal(t, comment.Content, "1 hour 1 minute")
}
diff --git a/models/migrate_test.go b/models/migrate_test.go
index b6525278ecfa..627fb1ae737d 100644
--- a/models/migrate_test.go
+++ b/models/migrate_test.go
@@ -21,7 +21,7 @@ import (
func TestMigrate_InsertMilestones(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
name := "milestonetest1"
ms := &issues_model.Milestone{
RepoID: repo.ID,
@@ -30,7 +30,7 @@ func TestMigrate_InsertMilestones(t *testing.T) {
err := InsertMilestones(ms)
assert.NoError(t, err)
unittest.AssertExistsAndLoadBean(t, ms)
- repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}).(*repo_model.Repository)
+ repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID})
assert.EqualValues(t, repo.NumMilestones+1, repoModified.NumMilestones)
unittest.CheckConsistencyFor(t, &issues_model.Milestone{})
@@ -39,10 +39,10 @@ func TestMigrate_InsertMilestones(t *testing.T) {
func assertCreateIssues(t *testing.T, isPull bool) {
assert.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
- milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}).(*issues_model.Milestone)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ milestone := unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1})
assert.EqualValues(t, milestone.ID, 1)
reaction := &issues_model.Reaction{
Type: "heart",
@@ -72,7 +72,7 @@ func assertCreateIssues(t *testing.T, isPull bool) {
err := InsertIssues(is)
assert.NoError(t, err)
- i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title}).(*issues_model.Issue)
+ i := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{Title: title})
assert.Nil(t, i.ForeignReference)
err = i.LoadAttributes(db.DefaultContext)
assert.NoError(t, err)
@@ -90,9 +90,9 @@ func TestMigrate_CreateIssuesIsPullTrue(t *testing.T) {
func TestMigrate_InsertIssueComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
_ = issue.LoadRepo(db.DefaultContext)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: issue.Repo.OwnerID})
reaction := &issues_model.Reaction{
Type: "heart",
UserID: owner.ID,
@@ -109,7 +109,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) {
err := InsertIssueComments([]*issues_model.Comment{comment})
assert.NoError(t, err)
- issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments)
unittest.CheckConsistencyFor(t, &issues_model.Issue{})
@@ -118,8 +118,8 @@ func TestMigrate_InsertIssueComments(t *testing.T) {
func TestMigrate_InsertPullRequests(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
reponame := "repo1"
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame}).(*repo_model.Repository)
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: reponame})
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
i := &issues_model.Issue{
RepoID: repo.ID,
@@ -138,7 +138,7 @@ func TestMigrate_InsertPullRequests(t *testing.T) {
err := InsertPullRequests(p)
assert.NoError(t, err)
- _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID}).(*issues_model.PullRequest)
+ _ = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{IssueID: i.ID})
unittest.CheckConsistencyFor(t, &issues_model.Issue{}, &issues_model.PullRequest{})
}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 2719f45efbbb..30c4ad250c08 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -406,6 +406,8 @@ var migrations = []Migration{
NewMigration("Drop old CredentialID column", dropOldCredentialIDColumn),
// v223 -> v224
NewMigration("Rename CredentialIDBytes column to CredentialID", renameCredentialIDBytes),
+ // v224 -> v225
+ NewMigration("Add badges to users", creatUserBadgesTable),
}
// GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go
index 46782f24a100..53e4f3539564 100644
--- a/models/migrations/migrations_test.go
+++ b/models/migrations/migrations_test.go
@@ -66,11 +66,10 @@ func TestMain(m *testing.M) {
setting.SetCustomPathAndConf("", "", "")
setting.LoadForTest()
- if err = git.InitOnceWithSync(context.Background()); err != nil {
- fmt.Printf("Unable to InitOnceWithSync: %v\n", err)
+ if err = git.InitFull(context.Background()); err != nil {
+ fmt.Printf("Unable to InitFull: %v\n", err)
os.Exit(1)
}
- git.CheckLFSVersion()
setting.InitDBConfig()
setting.NewLogServices(true)
@@ -207,7 +206,6 @@ func prepareTestEnv(t *testing.T, skip int, syncModels ...interface{}) (*xorm.En
deferFn := PrintCurrentTest(t, ourSkip)
assert.NoError(t, os.RemoveAll(setting.RepoRootPath))
assert.NoError(t, unittest.CopyDir(path.Join(filepath.Dir(setting.AppPath), "integrations/gitea-repositories-meta"), setting.RepoRootPath))
- assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil {
assert.NoError(t, err, "unable to read the new repo root: %v\n", err)
diff --git a/models/migrations/v220.go b/models/migrations/v220.go
index f5983582a30f..8138bc5bb149 100644
--- a/models/migrations/v220.go
+++ b/models/migrations/v220.go
@@ -12,18 +12,17 @@ import (
"xorm.io/xorm/schemas"
)
-func addContainerRepositoryProperty(x *xorm.Engine) error {
+func addContainerRepositoryProperty(x *xorm.Engine) (err error) {
switch x.Dialect().URI().DBType {
case schemas.SQLITE:
- _, err := x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
- if err != nil {
- return err
- }
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name || '/' || p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
+ case schemas.MSSQL:
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, u.lower_name + '/' + p.lower_name FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
default:
- _, err := x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?", packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
- if err != nil {
- return err
- }
+ _, err = x.Exec("INSERT INTO package_property (ref_type, ref_id, name, value) SELECT ?, p.id, ?, CONCAT(u.lower_name, '/', p.lower_name) FROM package p JOIN `user` u ON p.owner_id = u.id WHERE p.type = ?",
+ packages_model.PropertyTypePackage, container_module.PropertyRepository, packages_model.TypeContainer)
}
- return nil
+ return err
}
diff --git a/models/migrations/v224.go b/models/migrations/v224.go
new file mode 100644
index 000000000000..d684d538df22
--- /dev/null
+++ b/models/migrations/v224.go
@@ -0,0 +1,28 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package migrations
+
+import (
+ "xorm.io/xorm"
+)
+
+func creatUserBadgesTable(x *xorm.Engine) error {
+ type Badge struct {
+ ID int64 `xorm:"pk autoincr"`
+ Description string
+ ImageURL string
+ }
+
+ type userBadge struct {
+ ID int64 `xorm:"pk autoincr"`
+ BadgeID int64
+ UserID int64 `xorm:"INDEX"`
+ }
+
+ if err := x.Sync2(new(Badge)); err != nil {
+ return err
+ }
+ return x.Sync2(new(userBadge))
+}
diff --git a/models/notification_test.go b/models/notification_test.go
index 16ff02d6c05b..340fb4337ae5 100644
--- a/models/notification_test.go
+++ b/models/notification_test.go
@@ -17,22 +17,22 @@ import (
func TestCreateOrUpdateIssueNotifications(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1})
assert.NoError(t, CreateOrUpdateIssueNotifications(issue.ID, 0, 2, 0))
// User 9 is inactive, thus notifications for user 1 and 4 are created
- notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID}).(*Notification)
+ notf := unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 1, IssueID: issue.ID})
assert.Equal(t, NotificationStatusUnread, notf.Status)
unittest.CheckConsistencyFor(t, &issues_model.Issue{ID: issue.ID})
- notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID}).(*Notification)
+ notf = unittest.AssertExistsAndLoadBean(t, &Notification{UserID: 4, IssueID: issue.ID})
assert.Equal(t, NotificationStatusUnread, notf.Status)
}
func TestNotificationsForUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
statuses := []NotificationStatus{NotificationStatusRead, NotificationStatusUnread}
notfs, err := NotificationsForUser(db.DefaultContext, user, statuses, 1, 10)
assert.NoError(t, err)
@@ -48,7 +48,7 @@ func TestNotificationsForUser(t *testing.T) {
func TestNotification_GetRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}).(*Notification)
+ notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1})
repo, err := notf.GetRepo()
assert.NoError(t, err)
assert.Equal(t, repo, notf.Repository)
@@ -57,7 +57,7 @@ func TestNotification_GetRepo(t *testing.T) {
func TestNotification_GetIssue(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1}).(*Notification)
+ notf := unittest.AssertExistsAndLoadBean(t, &Notification{RepoID: 1})
issue, err := notf.GetIssue()
assert.NoError(t, err)
assert.Equal(t, issue, notf.Issue)
@@ -66,7 +66,7 @@ func TestNotification_GetIssue(t *testing.T) {
func TestGetNotificationCount(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
cnt, err := GetNotificationCount(db.DefaultContext, user, NotificationStatusRead)
assert.NoError(t, err)
assert.EqualValues(t, 0, cnt)
@@ -78,9 +78,9 @@ func TestGetNotificationCount(t *testing.T) {
func TestSetNotificationStatus(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
notf := unittest.AssertExistsAndLoadBean(t,
- &Notification{UserID: user.ID, Status: NotificationStatusRead}).(*Notification)
+ &Notification{UserID: user.ID, Status: NotificationStatusRead})
_, err := SetNotificationStatus(notf.ID, user, NotificationStatusPinned)
assert.NoError(t, err)
unittest.AssertExistsAndLoadBean(t,
@@ -94,13 +94,13 @@ func TestSetNotificationStatus(t *testing.T) {
func TestUpdateNotificationStatuses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
notfUnread := unittest.AssertExistsAndLoadBean(t,
- &Notification{UserID: user.ID, Status: NotificationStatusUnread}).(*Notification)
+ &Notification{UserID: user.ID, Status: NotificationStatusUnread})
notfRead := unittest.AssertExistsAndLoadBean(t,
- &Notification{UserID: user.ID, Status: NotificationStatusRead}).(*Notification)
+ &Notification{UserID: user.ID, Status: NotificationStatusRead})
notfPinned := unittest.AssertExistsAndLoadBean(t,
- &Notification{UserID: user.ID, Status: NotificationStatusPinned}).(*Notification)
+ &Notification{UserID: user.ID, Status: NotificationStatusPinned})
assert.NoError(t, UpdateNotificationStatuses(user, NotificationStatusUnread, NotificationStatusRead))
unittest.AssertExistsAndLoadBean(t,
&Notification{ID: notfUnread.ID, Status: NotificationStatusRead})
diff --git a/models/org_team_test.go b/models/org_team_test.go
index 35ee9af85a8e..a0de6d73f1f6 100644
--- a/models/org_team_test.go
+++ b/models/org_team_test.go
@@ -23,7 +23,7 @@ func TestTeam_AddMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, userID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, AddTeamMember(team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
@@ -37,7 +37,7 @@ func TestTeam_RemoveMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, userID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, RemoveTeamMember(team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
@@ -47,7 +47,7 @@ func TestTeam_RemoveMember(t *testing.T) {
testSuccess(3, 2)
testSuccess(3, unittest.NonexistentID)
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
err := RemoveTeamMember(team, 2)
assert.True(t, organization.IsErrLastOrgOwner(err))
}
@@ -56,7 +56,7 @@ func TestTeam_HasRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, repoID int64, expected bool) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.Equal(t, expected, HasRepository(team, repoID))
}
test(1, 1, false)
@@ -72,8 +72,8 @@ func TestTeam_AddRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, repoID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
assert.NoError(t, AddRepository(team, repo))
unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID})
@@ -81,8 +81,8 @@ func TestTeam_AddRepository(t *testing.T) {
testSuccess(2, 3)
testSuccess(2, 5)
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.Error(t, AddRepository(team, repo))
unittest.CheckConsistencyFor(t, &organization.Team{ID: 1}, &repo_model.Repository{ID: 1})
}
@@ -91,7 +91,7 @@ func TestTeam_RemoveRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, repoID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, RemoveRepository(team, repoID))
unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: teamID, RepoID: repoID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &repo_model.Repository{ID: repoID})
@@ -120,17 +120,17 @@ func TestUpdateTeam(t *testing.T) {
// successful update
assert.NoError(t, unittest.PrepareTestDatabase())
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "newname"
team.Name = "newName"
team.Description = strings.Repeat("A long description!", 100)
team.AccessMode = perm.AccessModeAdmin
assert.NoError(t, UpdateTeam(team, true, false))
- team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"}).(*organization.Team)
+ team = unittest.AssertExistsAndLoadBean(t, &organization.Team{Name: "newName"})
assert.True(t, strings.HasPrefix(team.Description, "A long description!"))
- access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3}).(*access_model.Access)
+ access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3})
assert.EqualValues(t, perm.AccessModeAdmin, access.Mode)
unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID})
@@ -140,7 +140,7 @@ func TestUpdateTeam2(t *testing.T) {
// update to already-existing team
assert.NoError(t, unittest.PrepareTestDatabase())
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
team.LowerName = "owners"
team.Name = "Owners"
team.Description = strings.Repeat("A long description!", 100)
@@ -153,15 +153,15 @@ func TestUpdateTeam2(t *testing.T) {
func TestDeleteTeam(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
assert.NoError(t, DeleteTeam(team))
unittest.AssertNotExistsBean(t, &organization.Team{ID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamRepo{TeamID: team.ID})
unittest.AssertNotExistsBean(t, &organization.TeamUser{TeamID: team.ID})
// check that team members don't have "leftover" access to repos
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
accessMode, err := access_model.AccessLevel(user, repo)
assert.NoError(t, err)
assert.True(t, accessMode < perm.AccessModeWrite)
@@ -171,7 +171,7 @@ func TestAddTeamMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, userID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, AddTeamMember(team, userID))
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID}, &user_model.User{ID: team.OrgID})
@@ -185,7 +185,7 @@ func TestRemoveTeamMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(teamID, userID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, RemoveTeamMember(team, userID))
unittest.AssertNotExistsBean(t, &organization.TeamUser{UID: userID, TeamID: teamID})
unittest.CheckConsistencyFor(t, &organization.Team{ID: teamID})
@@ -195,15 +195,15 @@ func TestRemoveTeamMember(t *testing.T) {
testSuccess(3, 2)
testSuccess(3, unittest.NonexistentID)
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
err := RemoveTeamMember(team, 2)
assert.True(t, organization.IsErrLastOrgOwner(err))
}
func TestRepository_RecalculateAccesses3(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team)
- user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User)
+ team5 := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
+ user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
has, err := db.GetEngine(db.DefaultContext).Get(&access_model.Access{UserID: 29, RepoID: 23})
assert.NoError(t, err)
diff --git a/models/org_test.go b/models/org_test.go
index af11bed280f4..23b417119ede 100644
--- a/models/org_test.go
+++ b/models/org_test.go
@@ -16,14 +16,14 @@ import (
func TestUser_RemoveMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
// remove a user that is a member
unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{UID: 4, OrgID: 3})
prevNumMembers := org.NumMembers
assert.NoError(t, RemoveOrgUser(org.ID, 4))
unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 4, OrgID: 3})
- org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
assert.Equal(t, prevNumMembers-1, org.NumMembers)
// remove a user that is not a member
@@ -31,7 +31,7 @@ func TestUser_RemoveMember(t *testing.T) {
prevNumMembers = org.NumMembers
assert.NoError(t, RemoveOrgUser(org.ID, 5))
unittest.AssertNotExistsBean(t, &organization.OrgUser{UID: 5, OrgID: 3})
- org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
assert.Equal(t, prevNumMembers, org.NumMembers)
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
@@ -40,14 +40,14 @@ func TestUser_RemoveMember(t *testing.T) {
func TestRemoveOrgUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID, userID int64) {
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
expectedNumMembers := org.NumMembers
if unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) {
expectedNumMembers--
}
assert.NoError(t, RemoveOrgUser(orgID, userID))
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: orgID, UID: userID})
- org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User)
+ org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
assert.EqualValues(t, expectedNumMembers, org.NumMembers)
}
testSuccess(3, 4)
diff --git a/models/organization/org_test.go b/models/organization/org_test.go
index 3a135498a337..0fba6e25925c 100644
--- a/models/organization/org_test.go
+++ b/models/organization/org_test.go
@@ -31,7 +31,7 @@ func TestUser_IsOwnedBy(t *testing.T) {
{2, 2, false}, // user2 is not an organization
{2, 3, false},
} {
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID})
isOwner, err := org.IsOwnedBy(testCase.UserID)
assert.NoError(t, err)
assert.Equal(t, testCase.ExpectedOwner, isOwner)
@@ -52,7 +52,7 @@ func TestUser_IsOrgMember(t *testing.T) {
{2, 2, false}, // user2 is not an organization
{2, 3, false},
} {
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: testCase.OrgID})
isMember, err := org.IsOrgMember(testCase.UserID)
assert.NoError(t, err)
assert.Equal(t, testCase.ExpectedMember, isMember)
@@ -61,7 +61,7 @@ func TestUser_IsOrgMember(t *testing.T) {
func TestUser_GetTeam(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
team, err := org.GetTeam("team1")
assert.NoError(t, err)
assert.Equal(t, org.ID, team.OrgID)
@@ -70,26 +70,26 @@ func TestUser_GetTeam(t *testing.T) {
_, err = org.GetTeam("does not exist")
assert.True(t, organization.IsErrTeamNotExist(err))
- nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}).(*organization.Organization)
+ nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2})
_, err = nonOrg.GetTeam("team")
assert.True(t, organization.IsErrTeamNotExist(err))
}
func TestUser_GetOwnerTeam(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
team, err := org.GetOwnerTeam()
assert.NoError(t, err)
assert.Equal(t, org.ID, team.OrgID)
- nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2}).(*organization.Organization)
+ nonOrg := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 2})
_, err = nonOrg.GetOwnerTeam()
assert.True(t, organization.IsErrTeamNotExist(err))
}
func TestUser_GetTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
teams, err := org.LoadTeams()
assert.NoError(t, err)
if assert.Len(t, teams, 4) {
@@ -102,7 +102,7 @@ func TestUser_GetTeams(t *testing.T) {
func TestUser_GetMembers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
members, _, err := org.GetMembers()
assert.NoError(t, err)
if assert.Len(t, members, 3) {
@@ -275,7 +275,7 @@ func TestChangeOrgUserStatus(t *testing.T) {
testSuccess := func(orgID, userID int64, public bool) {
assert.NoError(t, organization.ChangeOrgUserStatus(orgID, userID, public))
- orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID}).(*organization.OrgUser)
+ orgUser := unittest.AssertExistsAndLoadBean(t, &organization.OrgUser{OrgID: orgID, UID: userID})
assert.Equal(t, public, orgUser.IsPublic)
}
@@ -287,7 +287,7 @@ func TestChangeOrgUserStatus(t *testing.T) {
func TestUser_GetUserTeamIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expected []int64) {
teamIDs, err := org.GetUserTeamIDs(userID)
assert.NoError(t, err)
@@ -300,7 +300,7 @@ func TestUser_GetUserTeamIDs(t *testing.T) {
func TestAccessibleReposEnv_CountRepos(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID, expectedCount int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
assert.NoError(t, err)
@@ -314,7 +314,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) {
func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID, _, pageSize int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
assert.NoError(t, err)
@@ -328,7 +328,7 @@ func TestAccessibleReposEnv_RepoIDs(t *testing.T) {
func TestAccessibleReposEnv_Repos(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
assert.NoError(t, err)
@@ -337,7 +337,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
- &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ &repo_model.Repository{ID: repoID})
}
assert.Equal(t, expectedRepos, repos)
}
@@ -347,7 +347,7 @@ func TestAccessibleReposEnv_Repos(t *testing.T) {
func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
testSuccess := func(userID int64, expectedRepoIDs []int64) {
env, err := organization.AccessibleReposEnv(db.DefaultContext, org, userID)
assert.NoError(t, err)
@@ -356,7 +356,7 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
expectedRepos := make([]*repo_model.Repository, len(expectedRepoIDs))
for i, repoID := range expectedRepoIDs {
expectedRepos[i] = unittest.AssertExistsAndLoadBean(t,
- &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ &repo_model.Repository{ID: repoID})
}
assert.Equal(t, expectedRepos, repos)
}
@@ -366,8 +366,8 @@ func TestAccessibleReposEnv_MirrorRepos(t *testing.T) {
func TestHasOrgVisibleTypePublic(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
const newOrgName = "test-org-public"
org := &organization.Organization{
@@ -378,7 +378,7 @@ func TestHasOrgVisibleTypePublic(t *testing.T) {
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
assert.NoError(t, organization.CreateOrganization(org, owner))
org = unittest.AssertExistsAndLoadBean(t,
- &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization)
+ &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3)
test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil)
@@ -389,8 +389,8 @@ func TestHasOrgVisibleTypePublic(t *testing.T) {
func TestHasOrgVisibleTypeLimited(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
const newOrgName = "test-org-limited"
org := &organization.Organization{
@@ -401,7 +401,7 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) {
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
assert.NoError(t, organization.CreateOrganization(org, owner))
org = unittest.AssertExistsAndLoadBean(t,
- &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization)
+ &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3)
test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil)
@@ -412,8 +412,8 @@ func TestHasOrgVisibleTypeLimited(t *testing.T) {
func TestHasOrgVisibleTypePrivate(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user3 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
const newOrgName = "test-org-private"
org := &organization.Organization{
@@ -424,7 +424,7 @@ func TestHasOrgVisibleTypePrivate(t *testing.T) {
unittest.AssertNotExistsBean(t, &user_model.User{Name: org.Name, Type: user_model.UserTypeOrganization})
assert.NoError(t, organization.CreateOrganization(org, owner))
org = unittest.AssertExistsAndLoadBean(t,
- &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization}).(*organization.Organization)
+ &organization.Organization{Name: org.Name, Type: user_model.UserTypeOrganization})
test1 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), owner)
test2 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), user3)
test3 := organization.HasOrgOrUserVisible(db.DefaultContext, org.AsUser(), nil)
@@ -453,8 +453,8 @@ func TestGetUsersWhoCanCreateOrgRepo(t *testing.T) {
func TestUser_RemoveOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID}).(*repo_model.Repository)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: org.ID})
// remove a repo that does belong to org
unittest.AssertExistsAndLoadBean(t, &organization.TeamRepo{RepoID: repo.ID, OrgID: org.ID})
@@ -478,7 +478,7 @@ func TestCreateOrganization(t *testing.T) {
// successful creation of org
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
const newOrgName = "neworg"
org := &organization.Organization{
Name: newOrgName,
@@ -487,9 +487,9 @@ func TestCreateOrganization(t *testing.T) {
unittest.AssertNotExistsBean(t, &user_model.User{Name: newOrgName, Type: user_model.UserTypeOrganization})
assert.NoError(t, organization.CreateOrganization(org, owner))
org = unittest.AssertExistsAndLoadBean(t,
- &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization}).(*organization.Organization)
+ &organization.Organization{Name: newOrgName, Type: user_model.UserTypeOrganization})
ownerTeam := unittest.AssertExistsAndLoadBean(t,
- &organization.Team{Name: organization.OwnerTeamName, OrgID: org.ID}).(*organization.Team)
+ &organization.Team{Name: organization.OwnerTeamName, OrgID: org.ID})
unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{UID: owner.ID, TeamID: ownerTeam.ID})
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
}
@@ -498,7 +498,7 @@ func TestCreateOrganization2(t *testing.T) {
// unauthorized creation of org
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
const newOrgName = "neworg"
org := &organization.Organization{
Name: newOrgName,
@@ -516,7 +516,7 @@ func TestCreateOrganization3(t *testing.T) {
// create org with same name as existent org
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
org := &organization.Organization{Name: "user3"} // should already exist
unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: org.Name}) // sanity check
err := organization.CreateOrganization(org, owner)
@@ -529,7 +529,7 @@ func TestCreateOrganization4(t *testing.T) {
// create org with unusable name
assert.NoError(t, unittest.PrepareTestDatabase())
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
err := organization.CreateOrganization(&organization.Organization{Name: "assets"}, owner)
assert.Error(t, err)
assert.True(t, db.IsErrNameReserved(err))
diff --git a/models/organization/org_user_test.go b/models/organization/org_user_test.go
index 22ee5217f95e..aed3ea23cf8c 100644
--- a/models/organization/org_user_test.go
+++ b/models/organization/org_user_test.go
@@ -130,7 +130,7 @@ func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]bo
func TestAddOrgUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(orgID, userID int64, isPublic bool) {
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
expectedNumMembers := org.NumMembers
if !unittest.BeanExists(t, &organization.OrgUser{OrgID: orgID, UID: userID}) {
expectedNumMembers++
@@ -139,7 +139,7 @@ func TestAddOrgUser(t *testing.T) {
ou := &organization.OrgUser{OrgID: orgID, UID: userID}
unittest.AssertExistsAndLoadBean(t, ou)
assert.Equal(t, isPublic, ou.IsPublic)
- org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}).(*user_model.User)
+ org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID})
assert.EqualValues(t, expectedNumMembers, org.NumMembers)
}
diff --git a/models/organization/team_test.go b/models/organization/team_test.go
index 829c440c2938..c8d58a0eb7a8 100644
--- a/models/organization/team_test.go
+++ b/models/organization/team_test.go
@@ -17,22 +17,22 @@ import (
func TestTeam_IsOwnerTeam(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
assert.True(t, team.IsOwnerTeam())
- team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team)
+ team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
assert.False(t, team.IsOwnerTeam())
}
func TestTeam_IsMember(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 1})
assert.True(t, team.IsMember(2))
assert.False(t, team.IsMember(4))
assert.False(t, team.IsMember(unittest.NonexistentID))
- team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2}).(*organization.Team)
+ team = unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 2})
assert.True(t, team.IsMember(2))
assert.True(t, team.IsMember(4))
assert.False(t, team.IsMember(unittest.NonexistentID))
@@ -42,7 +42,7 @@ func TestTeam_GetRepositories(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, team.GetRepositoriesCtx(db.DefaultContext))
assert.Len(t, team.Repos, team.NumRepos)
for _, repo := range team.Repos {
@@ -57,7 +57,7 @@ func TestTeam_GetMembers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, team.GetMembersCtx(db.DefaultContext))
assert.Len(t, team.Members, team.NumMembers)
for _, member := range team.Members {
@@ -126,7 +126,7 @@ func TestGetTeamMembers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
members, err := organization.GetTeamMembers(db.DefaultContext, &organization.SearchMembersOptions{
TeamID: teamID,
})
@@ -173,7 +173,7 @@ func TestHasTeamRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(teamID, repoID int64, expected bool) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.Equal(t, expected, organization.HasTeamRepo(db.DefaultContext, team.OrgID, teamID, repoID))
}
test(1, 1, false)
diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go
index 31819ccca1ab..dc753421d021 100644
--- a/models/packages/descriptor.go
+++ b/models/packages/descriptor.go
@@ -19,6 +19,7 @@ import (
"code.gitea.io/gitea/modules/packages/maven"
"code.gitea.io/gitea/modules/packages/npm"
"code.gitea.io/gitea/modules/packages/nuget"
+ "code.gitea.io/gitea/modules/packages/pub"
"code.gitea.io/gitea/modules/packages/pypi"
"code.gitea.io/gitea/modules/packages/rubygems"
@@ -143,6 +144,8 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc
metadata = &npm.Metadata{}
case TypeMaven:
metadata = &maven.Metadata{}
+ case TypePub:
+ metadata = &pub.Metadata{}
case TypePyPI:
metadata = &pypi.Metadata{}
case TypeRubyGems:
diff --git a/models/packages/package.go b/models/packages/package.go
index 97cfbc6cad20..39b1c83cfabf 100644
--- a/models/packages/package.go
+++ b/models/packages/package.go
@@ -39,6 +39,7 @@ const (
TypeMaven Type = "maven"
TypeNpm Type = "npm"
TypeNuGet Type = "nuget"
+ TypePub Type = "pub"
TypePyPI Type = "pypi"
TypeRubyGems Type = "rubygems"
)
@@ -62,6 +63,8 @@ func (pt Type) Name() string {
return "npm"
case TypeNuGet:
return "NuGet"
+ case TypePub:
+ return "Pub"
case TypePyPI:
return "PyPI"
case TypeRubyGems:
@@ -89,6 +92,8 @@ func (pt Type) SVGName() string {
return "gitea-npm"
case TypeNuGet:
return "gitea-nuget"
+ case TypePub:
+ return "gitea-pub"
case TypePyPI:
return "gitea-python"
case TypeRubyGems:
diff --git a/models/perm/access/access_test.go b/models/perm/access/access_test.go
index a5e0448d3db8..8e75792e0c79 100644
--- a/models/perm/access/access_test.go
+++ b/models/perm/access/access_test.go
@@ -23,21 +23,21 @@ import (
func TestAccessLevel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
- user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user5 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
+ user29 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 29})
// A public repository owned by User 2
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo1.IsPrivate)
// A private repository owned by Org 3
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
assert.True(t, repo3.IsPrivate)
// Another public repository
- repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo4 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
assert.False(t, repo4.IsPrivate)
// org. owned private repo
- repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository)
+ repo24 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24})
level, err := access_model.AccessLevel(user2, repo1)
assert.NoError(t, err)
@@ -74,13 +74,13 @@ func TestAccessLevel(t *testing.T) {
func TestHasAccess(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
// A public repository owned by User 2
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.False(t, repo1.IsPrivate)
// A private repository owned by Org 3
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
assert.True(t, repo2.IsPrivate)
has, err := access_model.HasAccess(db.DefaultContext, user1.ID, repo1)
@@ -100,7 +100,7 @@ func TestHasAccess(t *testing.T) {
func TestRepository_RecalculateAccesses(t *testing.T) {
// test with organization repo
assert.NoError(t, unittest.PrepareTestDatabase())
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
assert.NoError(t, repo1.GetOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 2, RepoID: 3})
@@ -117,7 +117,7 @@ func TestRepository_RecalculateAccesses(t *testing.T) {
func TestRepository_RecalculateAccesses2(t *testing.T) {
// test with non-organization repo
assert.NoError(t, unittest.PrepareTestDatabase())
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
assert.NoError(t, repo1.GetOwner(db.DefaultContext))
_, err := db.GetEngine(db.DefaultContext).Delete(&repo_model.Collaboration{UserID: 4, RepoID: 4})
@@ -133,11 +133,11 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// public non-organization repo
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -155,7 +155,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
}
// collaborator
- collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ collaborator := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, collaborator)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -164,7 +164,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
}
// owner
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -173,7 +173,7 @@ func TestRepoPermissionPublicNonOrgRepo(t *testing.T) {
}
// admin
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -186,11 +186,11 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// private non-organization repo
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4})
perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -216,7 +216,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
}
// owner
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -225,7 +225,7 @@ func TestRepoPermissionPrivateNonOrgRepo(t *testing.T) {
}
// admin
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -238,11 +238,11 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// public organization repo
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 32})
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -268,7 +268,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
}
// org member team owner
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -277,7 +277,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
}
// org member team tester
- member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User)
+ member := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, member)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -287,7 +287,7 @@ func TestRepoPermissionPublicOrgRepo(t *testing.T) {
assert.False(t, perm.CanWrite(unit.TypeCode))
// admin
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -300,11 +300,11 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// private organization repo
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 24})
assert.NoError(t, repo.LoadUnits(db.DefaultContext))
// plain user
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
perm, err := access_model.GetUserRepoPermission(db.DefaultContext, repo, user)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -330,7 +330,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
}
// org member team owner
- owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15}).(*user_model.User)
+ owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 15})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
assert.NoError(t, err)
for _, unit := range repo.Units {
@@ -339,7 +339,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
}
// update team information and then check permission
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: 5})
err = organization.UpdateTeamUnits(team, nil)
assert.NoError(t, err)
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, owner)
@@ -350,7 +350,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
}
// org member team tester
- tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ tester := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, tester)
assert.NoError(t, err)
assert.True(t, perm.CanWrite(unit.TypeIssues))
@@ -358,7 +358,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.False(t, perm.CanRead(unit.TypeCode))
// org member team reviewer
- reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20}).(*user_model.User)
+ reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 20})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, reviewer)
assert.NoError(t, err)
assert.False(t, perm.CanRead(unit.TypeIssues))
@@ -366,7 +366,7 @@ func TestRepoPermissionPrivateOrgRepo(t *testing.T) {
assert.True(t, perm.CanRead(unit.TypeCode))
// admin
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
perm, err = access_model.GetUserRepoPermission(db.DefaultContext, repo, admin)
assert.NoError(t, err)
for _, unit := range repo.Units {
diff --git a/models/repo/attachment.go b/models/repo/attachment.go
index ddddac2c3dcf..afec78a4254b 100644
--- a/models/repo/attachment.go
+++ b/models/repo/attachment.go
@@ -226,28 +226,6 @@ func DeleteAttachmentsByRelease(releaseID int64) error {
return err
}
-// IterateAttachment iterates attachments; it should not be used when Gitea is servicing users.
-func IterateAttachment(f func(attach *Attachment) error) error {
- var start int
- const batchSize = 100
- for {
- attachments := make([]*Attachment, 0, batchSize)
- if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&attachments); err != nil {
- return err
- }
- if len(attachments) == 0 {
- return nil
- }
- start += len(attachments)
-
- for _, attach := range attachments {
- if err := f(attach); err != nil {
- return err
- }
- }
- }
-}
-
// CountOrphanedAttachments returns the number of bad attachments
func CountOrphanedAttachments() (int64, error) {
return db.GetEngine(db.DefaultContext).Where("(issue_id > 0 and issue_id not in (select id from issue)) or (release_id > 0 and release_id not in (select id from `release`))").
diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go
index 2e6253d5610b..cbf46dd286d0 100644
--- a/models/repo/collaboration_test.go
+++ b/models/repo/collaboration_test.go
@@ -19,7 +19,7 @@ import (
func TestRepository_GetCollaborators(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID int64) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
collaborators, err := repo_model.GetCollaborators(db.DefaultContext, repo.ID, db.ListOptions{})
assert.NoError(t, err)
expectedLen, err := db.GetEngine(db.DefaultContext).Count(&repo_model.Collaboration{RepoID: repoID})
@@ -40,7 +40,7 @@ func TestRepository_IsCollaborator(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
test := func(repoID, userID int64, expected bool) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
actual, err := repo_model.IsCollaborator(db.DefaultContext, repo.ID, userID)
assert.NoError(t, err)
assert.Equal(t, expected, actual)
@@ -54,13 +54,13 @@ func TestRepository_IsCollaborator(t *testing.T) {
func TestRepository_ChangeCollaborationAccessMode(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin))
- collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}).(*repo_model.Collaboration)
+ collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4})
assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode)
- access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}).(*access_model.Access)
+ access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID})
assert.EqualValues(t, perm.AccessModeAdmin, access.Mode)
assert.NoError(t, repo_model.ChangeCollaborationAccessMode(repo, 4, perm.AccessModeAdmin))
diff --git a/models/repo/mirror.go b/models/repo/mirror.go
index 8f96e8cee185..e94bbda2c181 100644
--- a/models/repo/mirror.go
+++ b/models/repo/mirror.go
@@ -153,7 +153,9 @@ func (repos MirrorRepositoryList) loadAttributes(ctx context.Context) error {
}
for i := range repos {
repos[i].Mirror = set[repos[i].ID]
- repos[i].Mirror.Repo = repos[i]
+ if repos[i].Mirror != nil {
+ repos[i].Mirror.Repo = repos[i]
+ }
}
return nil
}
diff --git a/models/repo/redirect_test.go b/models/repo/redirect_test.go
index 05b105cf63ff..90114667e599 100644
--- a/models/repo/redirect_test.go
+++ b/models/repo/redirect_test.go
@@ -29,7 +29,7 @@ func TestNewRedirect(t *testing.T) {
// redirect to a completely new name
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
@@ -48,7 +48,7 @@ func TestNewRedirect2(t *testing.T) {
// redirect to previously used name
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "oldrepo1"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
@@ -67,7 +67,7 @@ func TestNewRedirect3(t *testing.T) {
// redirect for a previously-unredirected repo
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, repo_model.NewRedirect(db.DefaultContext, repo.OwnerID, repo.ID, repo.Name, "newreponame"))
unittest.AssertExistsAndLoadBean(t, &repo_model.Redirect{
diff --git a/models/repo/repo_list.go b/models/repo/repo_list.go
index 9de76fa5ffa1..1fa469fcfeb3 100644
--- a/models/repo/repo_list.go
+++ b/models/repo/repo_list.go
@@ -15,36 +15,12 @@ import (
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
- "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
"xorm.io/builder"
)
-// IterateRepository iterate repositories
-func IterateRepository(f func(repo *Repository) error) error {
- var start int
- batchSize := setting.Database.IterateBufferSize
- sess := db.GetEngine(db.DefaultContext)
- for {
- repos := make([]*Repository, 0, batchSize)
- if err := sess.Limit(batchSize, start).Find(&repos); err != nil {
- return err
- }
- if len(repos) == 0 {
- return nil
- }
- start += len(repos)
-
- for _, repo := range repos {
- if err := f(repo); err != nil {
- return err
- }
- }
- }
-}
-
// FindReposMapByIDs find repos as map
func FindReposMapByIDs(repoIDs []int64, res map[int64]*Repository) error {
return db.GetEngine(db.DefaultContext).In("id", repoIDs).Find(&res)
diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go
index 6f8b282a66aa..617ec12798d4 100644
--- a/models/repo/repo_test.go
+++ b/models/repo/repo_test.go
@@ -56,7 +56,7 @@ func TestGetPrivateRepositoryCount(t *testing.T) {
func TestRepoAPIURL(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user12/repo10", repo.APIURL())
}
diff --git a/models/repo/star_test.go b/models/repo/star_test.go
index aa72b1dac8c0..1b53e17d2732 100644
--- a/models/repo/star_test.go
+++ b/models/repo/star_test.go
@@ -36,7 +36,7 @@ func TestIsStaring(t *testing.T) {
func TestRepository_GetStargazers(t *testing.T) {
// repo with stargazers
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
gazers, err := repo_model.GetStargazers(repo, db.ListOptions{Page: 0})
assert.NoError(t, err)
if assert.Len(t, gazers, 1) {
@@ -47,7 +47,7 @@ func TestRepository_GetStargazers(t *testing.T) {
func TestRepository_GetStargazers2(t *testing.T) {
// repo with stargazers
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
gazers, err := repo_model.GetStargazers(repo, db.ListOptions{Page: 0})
assert.NoError(t, err)
assert.Len(t, gazers, 0)
diff --git a/models/repo/user_repo.go b/models/repo/user_repo.go
index 71e0c57550c5..6c0a241dc562 100644
--- a/models/repo/user_repo.go
+++ b/models/repo/user_repo.go
@@ -170,3 +170,15 @@ func GetReviewers(ctx context.Context, repo *Repository, doerID, posterID int64)
users := make([]*user_model.User, 0, 8)
return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
}
+
+// GetIssuePosters returns all users that have authored an issue/pull request for the given repository
+func GetIssuePosters(ctx context.Context, repo *Repository, isPull bool) ([]*user_model.User, error) {
+ users := make([]*user_model.User, 0, 8)
+ cond := builder.In("`user`.id",
+ builder.Select("poster_id").From("issue").Where(
+ builder.Eq{"repo_id": repo.ID}.
+ And(builder.Eq{"is_pull": isPull}),
+ ).GroupBy("poster_id"),
+ )
+ return users, db.GetEngine(ctx).Where(cond).OrderBy(user_model.GetOrderByName()).Find(&users)
+}
diff --git a/models/repo/user_repo_test.go b/models/repo/user_repo_test.go
index d024729b9cde..640914592090 100644
--- a/models/repo/user_repo_test.go
+++ b/models/repo/user_repo_test.go
@@ -17,13 +17,13 @@ import (
func TestRepoAssignees(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
users, err := repo_model.GetRepoAssignees(db.DefaultContext, repo2)
assert.NoError(t, err)
assert.Len(t, users, 1)
assert.Equal(t, users[0].ID, int64(2))
- repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}).(*repo_model.Repository)
+ repo21 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21})
users, err = repo_model.GetRepoAssignees(db.DefaultContext, repo21)
assert.NoError(t, err)
assert.Len(t, users, 3)
@@ -36,7 +36,7 @@ func TestRepoGetReviewers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// test public repo
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
ctx := db.DefaultContext
reviewers, err := repo_model.GetReviewers(ctx, repo1, 2, 2)
@@ -54,7 +54,7 @@ func TestRepoGetReviewers(t *testing.T) {
assert.Len(t, reviewers, 3)
// test private user repo
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
reviewers, err = repo_model.GetReviewers(ctx, repo2, 2, 4)
assert.NoError(t, err)
@@ -62,7 +62,7 @@ func TestRepoGetReviewers(t *testing.T) {
assert.EqualValues(t, reviewers[0].ID, 2)
// test private org repo
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
reviewers, err = repo_model.GetReviewers(ctx, repo3, 2, 1)
assert.NoError(t, err)
diff --git a/models/repo/watch_test.go b/models/repo/watch_test.go
index 3875e63fd873..18a2d5d5fdf3 100644
--- a/models/repo/watch_test.go
+++ b/models/repo/watch_test.go
@@ -30,7 +30,7 @@ func TestIsWatching(t *testing.T) {
func TestGetWatchers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watches, err := repo_model.GetWatchers(db.DefaultContext, repo.ID)
assert.NoError(t, err)
// One watchers are inactive, thus minus 1
@@ -47,7 +47,7 @@ func TestGetWatchers(t *testing.T) {
func TestRepository_GetWatchers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watchers, err := repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
@@ -55,7 +55,7 @@ func TestRepository_GetWatchers(t *testing.T) {
unittest.AssertExistsAndLoadBean(t, &repo_model.Watch{UserID: watcher.ID, RepoID: repo.ID})
}
- repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9}).(*repo_model.Repository)
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 9})
watchers, err = repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, 0)
@@ -64,7 +64,7 @@ func TestRepository_GetWatchers(t *testing.T) {
func TestWatchIfAuto(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
watchers, err := repo_model.GetRepoWatchers(repo.ID, db.ListOptions{Page: 1})
assert.NoError(t, err)
assert.Len(t, watchers, repo.NumWatches)
diff --git a/models/repo/wiki_test.go b/models/repo/wiki_test.go
index 339289e05d86..863173627628 100644
--- a/models/repo/wiki_test.go
+++ b/models/repo/wiki_test.go
@@ -18,7 +18,7 @@ import (
func TestRepository_WikiCloneLink(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
cloneLink := repo.WikiCloneLink()
assert.Equal(t, "ssh://sshuser@try.gitea.io:3000/user2/repo1.wiki.git", cloneLink.SSH)
assert.Equal(t, "https://try.gitea.io/user2/repo1.wiki.git", cloneLink.HTTPS)
@@ -32,15 +32,15 @@ func TestWikiPath(t *testing.T) {
func TestRepository_WikiPath(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
expected := filepath.Join(setting.RepoRootPath, "user2/repo1.wiki.git")
assert.Equal(t, expected, repo.WikiPath())
}
func TestRepository_HasWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.True(t, repo1.HasWiki())
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.False(t, repo2.HasWiki())
}
diff --git a/models/repo_collaboration_test.go b/models/repo_collaboration_test.go
index 4cf4d612184c..72b354f1a5db 100644
--- a/models/repo_collaboration_test.go
+++ b/models/repo_collaboration_test.go
@@ -19,9 +19,9 @@ func TestRepository_AddCollaborator(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(repoID, userID int64) {
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
assert.NoError(t, repo.GetOwner(db.DefaultContext))
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
assert.NoError(t, AddCollaborator(repo, user))
unittest.CheckConsistencyFor(t, &repo_model.Repository{ID: repoID}, &user_model.User{ID: userID})
}
@@ -33,7 +33,7 @@ func TestRepository_AddCollaborator(t *testing.T) {
func TestRepository_DeleteCollaboration(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 4})
assert.NoError(t, repo.GetOwner(db.DefaultContext))
assert.NoError(t, DeleteCollaboration(repo, 4))
unittest.AssertNotExistsBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4})
diff --git a/models/repo_transfer_test.go b/models/repo_transfer_test.go
index 9125bb8c8dfe..7904b04e98c3 100644
--- a/models/repo_transfer_test.go
+++ b/models/repo_transfer_test.go
@@ -17,8 +17,8 @@ import (
func TestRepositoryTransfer(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
transfer, err := GetPendingRepositoryTransfer(repo)
assert.NoError(t, err)
@@ -32,7 +32,7 @@ func TestRepositoryTransfer(t *testing.T) {
assert.Nil(t, transfer)
assert.True(t, IsErrNoPendingTransfer(err))
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, CreatePendingRepositoryTransfer(doer, user2, repo.ID, nil))
@@ -41,7 +41,7 @@ func TestRepositoryTransfer(t *testing.T) {
assert.NoError(t, transfer.LoadAttributes())
assert.Equal(t, "user2", transfer.Recipient.Name)
- user6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user6 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Only transfer can be started at any given time
err = CreatePendingRepositoryTransfer(doer, user6, repo.ID, nil)
diff --git a/models/unittest/testdb.go b/models/unittest/testdb.go
index 7f9af553747c..58656f781f13 100644
--- a/models/unittest/testdb.go
+++ b/models/unittest/testdb.go
@@ -120,11 +120,9 @@ func MainTest(m *testing.M, testOpts *TestOptions) {
fatalTestError("util.CopyDir: %v\n", err)
}
- if err = git.InitOnceWithSync(context.Background()); err != nil {
+ if err = git.InitFull(context.Background()); err != nil {
fatalTestError("git.Init: %v\n", err)
}
- git.CheckLFSVersion()
-
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
if err != nil {
fatalTestError("unable to read the new repo root: %v\n", err)
@@ -206,8 +204,6 @@ func PrepareTestEnv(t testing.TB) {
assert.NoError(t, util.RemoveAll(setting.RepoRootPath))
metaPath := filepath.Join(giteaRoot, "integrations", "gitea-repositories-meta")
assert.NoError(t, CopyDir(metaPath, setting.RepoRootPath))
- assert.NoError(t, git.InitOnceWithSync(context.Background())) // the gitconfig has been removed above, so sync the gitconfig again
-
ownerDirs, err := os.ReadDir(setting.RepoRootPath)
assert.NoError(t, err)
for _, ownerDir := range ownerDirs {
diff --git a/models/unittest/unit_tests.go b/models/unittest/unit_tests.go
index 6c20c2781bb4..c8673debed02 100644
--- a/models/unittest/unit_tests.go
+++ b/models/unittest/unit_tests.go
@@ -55,7 +55,7 @@ func BeanExists(t assert.TestingT, bean interface{}, conditions ...interface{})
}
// AssertExistsAndLoadBean assert that a bean exists and load it from the test database
-func AssertExistsAndLoadBean(t assert.TestingT, bean interface{}, conditions ...interface{}) interface{} {
+func AssertExistsAndLoadBean[T any](t assert.TestingT, bean T, conditions ...interface{}) T {
exists, err := LoadBeanIfExists(bean, conditions...)
assert.NoError(t, err)
assert.True(t, exists,
diff --git a/models/user.go b/models/user.go
index 86a714e746bb..4afbb9bea5c7 100644
--- a/models/user.go
+++ b/models/user.go
@@ -85,6 +85,7 @@ func DeleteUser(ctx context.Context, u *user_model.User, purge bool) (err error)
&organization.TeamUser{UID: u.ID},
&issues_model.Stopwatch{UserID: u.ID},
&user_model.Setting{UserID: u.ID},
+ &user_model.UserBadge{UserID: u.ID},
&pull_model.AutoMerge{DoerID: u.ID},
&pull_model.ReviewState{UserID: u.ID},
); err != nil {
diff --git a/models/user/badge.go b/models/user/badge.go
new file mode 100644
index 000000000000..5ff840cb8c35
--- /dev/null
+++ b/models/user/badge.go
@@ -0,0 +1,42 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package user
+
+import (
+ "context"
+
+ "code.gitea.io/gitea/models/db"
+)
+
+// Badge represents a user badge
+type Badge struct {
+ ID int64 `xorm:"pk autoincr"`
+ Description string
+ ImageURL string
+}
+
+// UserBadge represents a user badge
+type UserBadge struct {
+ ID int64 `xorm:"pk autoincr"`
+ BadgeID int64
+ UserID int64 `xorm:"INDEX"`
+}
+
+func init() {
+ db.RegisterModel(new(Badge))
+ db.RegisterModel(new(UserBadge))
+}
+
+// GetUserBadges returns the user's badges.
+func GetUserBadges(ctx context.Context, u *User) ([]*Badge, int64, error) {
+ sess := db.GetEngine(ctx).
+ Select("`badge`.*").
+ Join("INNER", "user_badge", "`user_badge`.badge_id=badge.id").
+ Where("user_badge.user_id=?", u.ID)
+
+ badges := make([]*Badge, 0, 8)
+ count, err := sess.FindAndCount(&badges)
+ return badges, count, err
+}
diff --git a/models/user/search.go b/models/user/search.go
index f8e6c89f0680..0aa9949367af 100644
--- a/models/user/search.go
+++ b/models/user/search.go
@@ -9,7 +9,6 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
- "code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
@@ -125,28 +124,6 @@ func SearchUsers(opts *SearchUserOptions) (users []*User, _ int64, _ error) {
return users, count, sessQuery.Find(&users)
}
-// IterateUser iterate users
-func IterateUser(f func(user *User) error) error {
- var start int
- batchSize := setting.Database.IterateBufferSize
- for {
- users := make([]*User, 0, batchSize)
- if err := db.GetEngine(db.DefaultContext).Limit(batchSize, start).Find(&users); err != nil {
- return err
- }
- if len(users) == 0 {
- return nil
- }
- start += len(users)
-
- for _, user := range users {
- if err := f(user); err != nil {
- return err
- }
- }
- }
-}
-
// BuildCanSeeUserCondition creates a condition which can be used to restrict results to users/orgs the actor can see
func BuildCanSeeUserCondition(actor *User) builder.Cond {
if actor != nil {
diff --git a/models/user/user_test.go b/models/user/user_test.go
index 489ee3b05da3..940382cdafa2 100644
--- a/models/user/user_test.go
+++ b/models/user/user_test.go
@@ -22,7 +22,7 @@ import (
func TestOAuth2Application_LoadUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1}).(*auth.OAuth2Application)
+ app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1})
user, err := user_model.GetUserByID(app.UID)
assert.NoError(t, err)
assert.NotNil(t, user)
@@ -41,10 +41,10 @@ func TestGetUserEmailsByNames(t *testing.T) {
func TestCanCreateOrganization(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ admin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.True(t, admin.CanCreateOrganization())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.True(t, user.CanCreateOrganization())
// Disable user create organization permission.
user.AllowCreateOrganization = false
@@ -141,7 +141,7 @@ func TestEmailNotificationPreferences(t *testing.T) {
{user_model.EmailNotificationsEnabled, 8},
{user_model.EmailNotificationsOnMention, 9},
} {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.userID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.userID})
assert.Equal(t, test.expected, user.EmailNotifications())
// Try all possible settings
@@ -242,7 +242,7 @@ func TestCreateUserInvalidEmail(t *testing.T) {
func TestCreateUserEmailAlreadyUsed(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// add new user with user2's email
user.Name = "testuser"
@@ -288,18 +288,18 @@ func TestGetMaileableUsersByIDs(t *testing.T) {
func TestUpdateUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
user.KeepActivityPrivate = true
assert.NoError(t, user_model.UpdateUser(db.DefaultContext, user, false))
- user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.True(t, user.KeepActivityPrivate)
setting.Service.AllowedUserVisibilityModesSlice = []bool{true, false, false}
user.KeepActivityPrivate = false
user.Visibility = structs.VisibleTypePrivate
assert.Error(t, user_model.UpdateUser(db.DefaultContext, user, false))
- user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.True(t, user.KeepActivityPrivate)
user.Email = "no mail@mail.org"
@@ -310,7 +310,7 @@ func TestNewUserRedirect(t *testing.T) {
// redirect to a completely new name
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
@@ -327,7 +327,7 @@ func TestNewUserRedirect2(t *testing.T) {
// redirect to previously used name
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
@@ -344,7 +344,7 @@ func TestNewUserRedirect3(t *testing.T) {
// redirect for a previously-unredirected user
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
diff --git a/models/user_heatmap_test.go b/models/user_heatmap_test.go
index 9361cb3452fa..1ff7bc6ed213 100644
--- a/models/user_heatmap_test.go
+++ b/models/user_heatmap_test.go
@@ -63,7 +63,7 @@ func TestGetUserHeatmapDataByUser(t *testing.T) {
defer timeutil.Unset()
for _, tc := range testCases {
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: tc.userID})
doer := &user_model.User{ID: tc.doerID}
_, err := unittest.LoadBeanIfExists(doer)
diff --git a/models/webhook/webhook.go b/models/webhook/webhook.go
index 1b79a414ade5..478a6a29ff23 100644
--- a/models/webhook/webhook.go
+++ b/models/webhook/webhook.go
@@ -399,6 +399,10 @@ func CreateWebhook(ctx context.Context, w *Webhook) error {
// CreateWebhooks creates multiple web hooks
func CreateWebhooks(ctx context.Context, ws []*Webhook) error {
+ // xorm returns err "no element on slice when insert" for empty slices.
+ if len(ws) == 0 {
+ return nil
+ }
for i := 0; i < len(ws); i++ {
ws[i].Type = strings.TrimSpace(ws[i].Type)
}
diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go
index 4bc811586d9a..1d77ee2a41ad 100644
--- a/models/webhook/webhook_test.go
+++ b/models/webhook/webhook_test.go
@@ -31,14 +31,14 @@ func TestIsValidHookContentType(t *testing.T) {
func TestWebhook_History(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook)
+ webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
tasks, err := webhook.History(0)
assert.NoError(t, err)
if assert.Len(t, tasks, 1) {
assert.Equal(t, int64(1), tasks[0].ID)
}
- webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}).(*Webhook)
+ webhook = unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
tasks, err = webhook.History(0)
assert.NoError(t, err)
assert.Len(t, tasks, 0)
@@ -46,7 +46,7 @@ func TestWebhook_History(t *testing.T) {
func TestWebhook_UpdateEvent(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1}).(*Webhook)
+ webhook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 1})
hookEvent := &HookEvent{
PushOnly: true,
SendEverything: false,
@@ -162,7 +162,7 @@ func TestGetWebhooksByOrgID(t *testing.T) {
func TestUpdateWebhook(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2}).(*Webhook)
+ hook := unittest.AssertExistsAndLoadBean(t, &Webhook{ID: 2})
hook.IsActive = true
hook.ContentType = ContentTypeForm
unittest.AssertNotExistsBean(t, hook)
@@ -220,7 +220,7 @@ func TestCreateHookTask(t *testing.T) {
func TestUpdateHookTask(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1}).(*HookTask)
+ hook := unittest.AssertExistsAndLoadBean(t, &HookTask{ID: 1})
hook.PayloadContent = "new payload content"
hook.DeliveredString = "new delivered string"
hook.IsDelivered = true
diff --git a/modules/activitypub/client_test.go b/modules/activitypub/client_test.go
index b93ef5ac988a..62068d53b3df 100644
--- a/modules/activitypub/client_test.go
+++ b/modules/activitypub/client_test.go
@@ -23,7 +23,7 @@ import (
func TestActivityPubSignedPost(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pubID := "https://example.com/pubID"
c, err := NewClient(user, pubID)
assert.NoError(t, err)
diff --git a/modules/activitypub/user_settings_test.go b/modules/activitypub/user_settings_test.go
index 90c6f680f993..beefde232f56 100644
--- a/modules/activitypub/user_settings_test.go
+++ b/modules/activitypub/user_settings_test.go
@@ -17,7 +17,7 @@ import (
func TestUserSettings(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
pub, priv, err := GetKeyPair(user1)
assert.NoError(t, err)
pub1, err := GetPublicKey(user1)
diff --git a/modules/charset/ambiguous.go b/modules/charset/ambiguous.go
new file mode 100644
index 000000000000..9dab3b0951bf
--- /dev/null
+++ b/modules/charset/ambiguous.go
@@ -0,0 +1,54 @@
+// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "sort"
+ "strings"
+ "unicode"
+
+ "code.gitea.io/gitea/modules/translation"
+)
+
+// AmbiguousTablesForLocale provides the table of ambiguous characters for this locale.
+func AmbiguousTablesForLocale(locale translation.Locale) []*AmbiguousTable {
+ key := locale.Language()
+ var table *AmbiguousTable
+ var ok bool
+ for len(key) > 0 {
+ if table, ok = AmbiguousCharacters[key]; ok {
+ break
+ }
+ idx := strings.LastIndexAny(key, "-_")
+ if idx < 0 {
+ key = ""
+ } else {
+ key = key[:idx]
+ }
+ }
+ if table == nil {
+ table = AmbiguousCharacters["_default"]
+ }
+
+ return []*AmbiguousTable{
+ table,
+ AmbiguousCharacters["_common"],
+ }
+}
+
+func isAmbiguous(r rune, confusableTo *rune, tables ...*AmbiguousTable) bool {
+ for _, table := range tables {
+ if !unicode.Is(table.RangeTable, r) {
+ continue
+ }
+ i := sort.Search(len(table.Confusable), func(i int) bool {
+ return table.Confusable[i] >= r
+ })
+ (*confusableTo) = table.With[i]
+ return true
+ }
+ return false
+}
diff --git a/modules/charset/ambiguous/ambiguous.json b/modules/charset/ambiguous/ambiguous.json
new file mode 100644
index 000000000000..d0f69f6ae2b1
--- /dev/null
+++ b/modules/charset/ambiguous/ambiguous.json
@@ -0,0 +1 @@
+"{\"_common\":[8232,32,8233,32,5760,32,8192,32,8193,32,8194,32,8195,32,8196,32,8197,32,8198,32,8200,32,8201,32,8202,32,8287,32,8199,32,8239,32,2042,95,65101,95,65102,95,65103,95,8208,45,8209,45,8210,45,65112,45,1748,45,8259,45,727,45,8722,45,10134,45,11450,45,1549,44,1643,44,8218,44,184,44,42233,44,894,59,2307,58,2691,58,1417,58,1795,58,1796,58,5868,58,65072,58,6147,58,6153,58,8282,58,1475,58,760,58,42889,58,8758,58,720,58,42237,58,451,33,11601,33,660,63,577,63,2429,63,5038,63,42731,63,119149,46,8228,46,1793,46,1794,46,42510,46,68176,46,1632,46,1776,46,42232,46,1373,96,65287,96,8219,96,8242,96,1370,96,1523,96,8175,96,65344,96,900,96,8189,96,8125,96,8127,96,8190,96,697,96,884,96,712,96,714,96,715,96,756,96,699,96,701,96,700,96,702,96,42892,96,1497,96,2036,96,2037,96,5194,96,5836,96,94033,96,94034,96,65339,91,10088,40,10098,40,12308,40,64830,40,65341,93,10089,41,10099,41,12309,41,64831,41,10100,123,119060,123,10101,125,65342,94,8270,42,1645,42,8727,42,66335,42,5941,47,8257,47,8725,47,8260,47,9585,47,10187,47,10744,47,119354,47,12755,47,12339,47,11462,47,20031,47,12035,47,65340,92,65128,92,8726,92,10189,92,10741,92,10745,92,119311,92,119355,92,12756,92,20022,92,12034,92,42872,38,708,94,710,94,5869,43,10133,43,66203,43,8249,60,10094,60,706,60,119350,60,5176,60,5810,60,5120,61,11840,61,12448,61,42239,61,8250,62,10095,62,707,62,119351,62,5171,62,94015,62,8275,126,732,126,8128,126,8764,126,65372,124,65293,45,120784,50,120794,50,120804,50,120814,50,120824,50,130034,50,42842,50,423,50,1000,50,42564,50,5311,50,42735,50,119302,51,120785,51,120795,51,120805,51,120815,51,120825,51,130035,51,42923,51,540,51,439,51,42858,51,11468,51,1248,51,94011,51,71882,51,120786,52,120796,52,120806,52,120816,52,120826,52,130036,52,5070,52,71855,52,120787,53,120797,53,120807,53,120817,53,120827,53,130037,53,444,53,71867,53,120788,54,120798,54,120808,54,120818,54,120828,54,130038,54,11474,54,5102,54,71893,54,119314,55,120789,55,120799,55,120809,55,120819,55,120829,55,130039,55,66770,55,71878,55,2819,56,2538,56,2666,56,125131,56,120790,56,120800,56,120810,56,120820,56,120830,56,130040,56,547,56,546,56,66330,56,2663,57,2920,57,2541,57,3437,57,120791,57,120801,57,120811,57,120821,57,120831,57,130041,57,42862,57,11466,57,71884,57,71852,57,71894,57,9082,97,65345,97,119834,97,119886,97,119938,97,119990,97,120042,97,120094,97,120146,97,120198,97,120250,97,120302,97,120354,97,120406,97,120458,97,593,97,945,97,120514,97,120572,97,120630,97,120688,97,120746,97,65313,65,119808,65,119860,65,119912,65,119964,65,120016,65,120068,65,120120,65,120172,65,120224,65,120276,65,120328,65,120380,65,120432,65,913,65,120488,65,120546,65,120604,65,120662,65,120720,65,5034,65,5573,65,42222,65,94016,65,66208,65,119835,98,119887,98,119939,98,119991,98,120043,98,120095,98,120147,98,120199,98,120251,98,120303,98,120355,98,120407,98,120459,98,388,98,5071,98,5234,98,5551,98,65314,66,8492,66,119809,66,119861,66,119913,66,120017,66,120069,66,120121,66,120173,66,120225,66,120277,66,120329,66,120381,66,120433,66,42932,66,914,66,120489,66,120547,66,120605,66,120663,66,120721,66,5108,66,5623,66,42192,66,66178,66,66209,66,66305,66,65347,99,8573,99,119836,99,119888,99,119940,99,119992,99,120044,99,120096,99,120148,99,120200,99,120252,99,120304,99,120356,99,120408,99,120460,99,7428,99,1010,99,11429,99,43951,99,66621,99,128844,67,71922,67,71913,67,65315,67,8557,67,8450,67,8493,67,119810,67,119862,67,119914,67,119966,67,120018,67,120174,67,120226,67,120278,67,120330,67,120382,67,120434,67,1017,67,11428,67,5087,67,42202,67,66210,67,66306,67,66581,67,66844,67,8574,100,8518,100,119837,100,119889,100,119941,100,119993,100,120045,100,120097,100,120149,100,120201,100,120253,100,120305,100,120357,100,120409,100,120461,100,1281,100,5095,100,5231,100,42194,100,8558,68,8517,68,119811,68,119863,68,119915,68,119967,68,120019,68,120071,68,120123,68,120175,68,120227,68,120279,68,120331,68,120383,68,120435,68,5024,68,5598,68,5610,68,42195,68,8494,101,65349,101,8495,101,8519,101,119838,101,119890,101,119942,101,120046,101,120098,101,120150,101,120202,101,120254,101,120306,101,120358,101,120410,101,120462,101,43826,101,1213,101,8959,69,65317,69,8496,69,119812,69,119864,69,119916,69,120020,69,120072,69,120124,69,120176,69,120228,69,120280,69,120332,69,120384,69,120436,69,917,69,120492,69,120550,69,120608,69,120666,69,120724,69,11577,69,5036,69,42224,69,71846,69,71854,69,66182,69,119839,102,119891,102,119943,102,119995,102,120047,102,120099,102,120151,102,120203,102,120255,102,120307,102,120359,102,120411,102,120463,102,43829,102,42905,102,383,102,7837,102,1412,102,119315,70,8497,70,119813,70,119865,70,119917,70,120021,70,120073,70,120125,70,120177,70,120229,70,120281,70,120333,70,120385,70,120437,70,42904,70,988,70,120778,70,5556,70,42205,70,71874,70,71842,70,66183,70,66213,70,66853,70,65351,103,8458,103,119840,103,119892,103,119944,103,120048,103,120100,103,120152,103,120204,103,120256,103,120308,103,120360,103,120412,103,120464,103,609,103,7555,103,397,103,1409,103,119814,71,119866,71,119918,71,119970,71,120022,71,120074,71,120126,71,120178,71,120230,71,120282,71,120334,71,120386,71,120438,71,1292,71,5056,71,5107,71,42198,71,65352,104,8462,104,119841,104,119945,104,119997,104,120049,104,120101,104,120153,104,120205,104,120257,104,120309,104,120361,104,120413,104,120465,104,1211,104,1392,104,5058,104,65320,72,8459,72,8460,72,8461,72,119815,72,119867,72,119919,72,120023,72,120179,72,120231,72,120283,72,120335,72,120387,72,120439,72,919,72,120494,72,120552,72,120610,72,120668,72,120726,72,11406,72,5051,72,5500,72,42215,72,66255,72,731,105,9075,105,65353,105,8560,105,8505,105,8520,105,119842,105,119894,105,119946,105,119998,105,120050,105,120102,105,120154,105,120206,105,120258,105,120310,105,120362,105,120414,105,120466,105,120484,105,618,105,617,105,953,105,8126,105,890,105,120522,105,120580,105,120638,105,120696,105,120754,105,1110,105,42567,105,1231,105,43893,105,5029,105,71875,105,65354,106,8521,106,119843,106,119895,106,119947,106,119999,106,120051,106,120103,106,120155,106,120207,106,120259,106,120311,106,120363,106,120415,106,120467,106,1011,106,1112,106,65322,74,119817,74,119869,74,119921,74,119973,74,120025,74,120077,74,120129,74,120181,74,120233,74,120285,74,120337,74,120389,74,120441,74,42930,74,895,74,1032,74,5035,74,5261,74,42201,74,119844,107,119896,107,119948,107,120000,107,120052,107,120104,107,120156,107,120208,107,120260,107,120312,107,120364,107,120416,107,120468,107,8490,75,65323,75,119818,75,119870,75,119922,75,119974,75,120026,75,120078,75,120130,75,120182,75,120234,75,120286,75,120338,75,120390,75,120442,75,922,75,120497,75,120555,75,120613,75,120671,75,120729,75,11412,75,5094,75,5845,75,42199,75,66840,75,1472,108,8739,73,9213,73,65512,73,1633,108,1777,73,66336,108,125127,108,120783,73,120793,73,120803,73,120813,73,120823,73,130033,73,65321,73,8544,73,8464,73,8465,73,119816,73,119868,73,119920,73,120024,73,120128,73,120180,73,120232,73,120284,73,120336,73,120388,73,120440,73,65356,108,8572,73,8467,108,119845,108,119897,108,119949,108,120001,108,120053,108,120105,73,120157,73,120209,73,120261,73,120313,73,120365,73,120417,73,120469,73,448,73,120496,73,120554,73,120612,73,120670,73,120728,73,11410,73,1030,73,1216,73,1493,108,1503,108,1575,108,126464,108,126592,108,65166,108,65165,108,1994,108,11599,73,5825,73,42226,73,93992,73,66186,124,66313,124,119338,76,8556,76,8466,76,119819,76,119871,76,119923,76,120027,76,120079,76,120131,76,120183,76,120235,76,120287,76,120339,76,120391,76,120443,76,11472,76,5086,76,5290,76,42209,76,93974,76,71843,76,71858,76,66587,76,66854,76,65325,77,8559,77,8499,77,119820,77,119872,77,119924,77,120028,77,120080,77,120132,77,120184,77,120236,77,120288,77,120340,77,120392,77,120444,77,924,77,120499,77,120557,77,120615,77,120673,77,120731,77,1018,77,11416,77,5047,77,5616,77,5846,77,42207,77,66224,77,66321,77,119847,110,119899,110,119951,110,120003,110,120055,110,120107,110,120159,110,120211,110,120263,110,120315,110,120367,110,120419,110,120471,110,1400,110,1404,110,65326,78,8469,78,119821,78,119873,78,119925,78,119977,78,120029,78,120081,78,120185,78,120237,78,120289,78,120341,78,120393,78,120445,78,925,78,120500,78,120558,78,120616,78,120674,78,120732,78,11418,78,42208,78,66835,78,3074,111,3202,111,3330,111,3458,111,2406,111,2662,111,2790,111,3046,111,3174,111,3302,111,3430,111,3664,111,3792,111,4160,111,1637,111,1781,111,65359,111,8500,111,119848,111,119900,111,119952,111,120056,111,120108,111,120160,111,120212,111,120264,111,120316,111,120368,111,120420,111,120472,111,7439,111,7441,111,43837,111,959,111,120528,111,120586,111,120644,111,120702,111,120760,111,963,111,120532,111,120590,111,120648,111,120706,111,120764,111,11423,111,4351,111,1413,111,1505,111,1607,111,126500,111,126564,111,126596,111,65259,111,65260,111,65258,111,65257,111,1726,111,64428,111,64429,111,64427,111,64426,111,1729,111,64424,111,64425,111,64423,111,64422,111,1749,111,3360,111,4125,111,66794,111,71880,111,71895,111,66604,111,1984,79,2534,79,2918,79,12295,79,70864,79,71904,79,120782,79,120792,79,120802,79,120812,79,120822,79,130032,79,65327,79,119822,79,119874,79,119926,79,119978,79,120030,79,120082,79,120134,79,120186,79,120238,79,120290,79,120342,79,120394,79,120446,79,927,79,120502,79,120560,79,120618,79,120676,79,120734,79,11422,79,1365,79,11604,79,4816,79,2848,79,66754,79,42227,79,71861,79,66194,79,66219,79,66564,79,66838,79,9076,112,65360,112,119849,112,119901,112,119953,112,120005,112,120057,112,120109,112,120161,112,120213,112,120265,112,120317,112,120369,112,120421,112,120473,112,961,112,120530,112,120544,112,120588,112,120602,112,120646,112,120660,112,120704,112,120718,112,120762,112,120776,112,11427,112,65328,80,8473,80,119823,80,119875,80,119927,80,119979,80,120031,80,120083,80,120187,80,120239,80,120291,80,120343,80,120395,80,120447,80,929,80,120504,80,120562,80,120620,80,120678,80,120736,80,11426,80,5090,80,5229,80,42193,80,66197,80,119850,113,119902,113,119954,113,120006,113,120058,113,120110,113,120162,113,120214,113,120266,113,120318,113,120370,113,120422,113,120474,113,1307,113,1379,113,1382,113,8474,81,119824,81,119876,81,119928,81,119980,81,120032,81,120084,81,120188,81,120240,81,120292,81,120344,81,120396,81,120448,81,11605,81,119851,114,119903,114,119955,114,120007,114,120059,114,120111,114,120163,114,120215,114,120267,114,120319,114,120371,114,120423,114,120475,114,43847,114,43848,114,7462,114,11397,114,43905,114,119318,82,8475,82,8476,82,8477,82,119825,82,119877,82,119929,82,120033,82,120189,82,120241,82,120293,82,120345,82,120397,82,120449,82,422,82,5025,82,5074,82,66740,82,5511,82,42211,82,94005,82,65363,115,119852,115,119904,115,119956,115,120008,115,120060,115,120112,115,120164,115,120216,115,120268,115,120320,115,120372,115,120424,115,120476,115,42801,115,445,115,1109,115,43946,115,71873,115,66632,115,65331,83,119826,83,119878,83,119930,83,119982,83,120034,83,120086,83,120138,83,120190,83,120242,83,120294,83,120346,83,120398,83,120450,83,1029,83,1359,83,5077,83,5082,83,42210,83,94010,83,66198,83,66592,83,119853,116,119905,116,119957,116,120009,116,120061,116,120113,116,120165,116,120217,116,120269,116,120321,116,120373,116,120425,116,120477,116,8868,84,10201,84,128872,84,65332,84,119827,84,119879,84,119931,84,119983,84,120035,84,120087,84,120139,84,120191,84,120243,84,120295,84,120347,84,120399,84,120451,84,932,84,120507,84,120565,84,120623,84,120681,84,120739,84,11430,84,5026,84,42196,84,93962,84,71868,84,66199,84,66225,84,66325,84,119854,117,119906,117,119958,117,120010,117,120062,117,120114,117,120166,117,120218,117,120270,117,120322,117,120374,117,120426,117,120478,117,42911,117,7452,117,43854,117,43858,117,651,117,965,117,120534,117,120592,117,120650,117,120708,117,120766,117,1405,117,66806,117,71896,117,8746,85,8899,85,119828,85,119880,85,119932,85,119984,85,120036,85,120088,85,120140,85,120192,85,120244,85,120296,85,120348,85,120400,85,120452,85,1357,85,4608,85,66766,85,5196,85,42228,85,94018,85,71864,85,8744,118,8897,118,65366,118,8564,118,119855,118,119907,118,119959,118,120011,118,120063,118,120115,118,120167,118,120219,118,120271,118,120323,118,120375,118,120427,118,120479,118,7456,118,957,118,120526,118,120584,118,120642,118,120700,118,120758,118,1141,118,1496,118,71430,118,43945,118,71872,118,119309,86,1639,86,1783,86,8548,86,119829,86,119881,86,119933,86,119985,86,120037,86,120089,86,120141,86,120193,86,120245,86,120297,86,120349,86,120401,86,120453,86,1140,86,11576,86,5081,86,5167,86,42719,86,42214,86,93960,86,71840,86,66845,86,623,119,119856,119,119908,119,119960,119,120012,119,120064,119,120116,119,120168,119,120220,119,120272,119,120324,119,120376,119,120428,119,120480,119,7457,119,1121,119,1309,119,1377,119,71434,119,71438,119,71439,119,43907,119,71919,87,71910,87,119830,87,119882,87,119934,87,119986,87,120038,87,120090,87,120142,87,120194,87,120246,87,120298,87,120350,87,120402,87,120454,87,1308,87,5043,87,5076,87,42218,87,5742,120,10539,120,10540,120,10799,120,65368,120,8569,120,119857,120,119909,120,119961,120,120013,120,120065,120,120117,120,120169,120,120221,120,120273,120,120325,120,120377,120,120429,120,120481,120,5441,120,5501,120,5741,88,9587,88,66338,88,71916,88,65336,88,8553,88,119831,88,119883,88,119935,88,119987,88,120039,88,120091,88,120143,88,120195,88,120247,88,120299,88,120351,88,120403,88,120455,88,42931,88,935,88,120510,88,120568,88,120626,88,120684,88,120742,88,11436,88,11613,88,5815,88,42219,88,66192,88,66228,88,66327,88,66855,88,611,121,7564,121,65369,121,119858,121,119910,121,119962,121,120014,121,120066,121,120118,121,120170,121,120222,121,120274,121,120326,121,120378,121,120430,121,120482,121,655,121,7935,121,43866,121,947,121,8509,121,120516,121,120574,121,120632,121,120690,121,120748,121,1199,121,4327,121,71900,121,65337,89,119832,89,119884,89,119936,89,119988,89,120040,89,120092,89,120144,89,120196,89,120248,89,120300,89,120352,89,120404,89,120456,89,933,89,978,89,120508,89,120566,89,120624,89,120682,89,120740,89,11432,89,1198,89,5033,89,5053,89,42220,89,94019,89,71844,89,66226,89,119859,122,119911,122,119963,122,120015,122,120067,122,120119,122,120171,122,120223,122,120275,122,120327,122,120379,122,120431,122,120483,122,7458,122,43923,122,71876,122,66293,90,71909,90,65338,90,8484,90,8488,90,119833,90,119885,90,119937,90,119989,90,120041,90,120197,90,120249,90,120301,90,120353,90,120405,90,120457,90,918,90,120493,90,120551,90,120609,90,120667,90,120725,90,5059,90,42204,90,71849,90,65282,34,65284,36,65285,37,65286,38,65290,42,65291,43,65294,46,65295,47,65296,48,65297,49,65298,50,65299,51,65300,52,65301,53,65302,54,65303,55,65304,56,65305,57,65308,60,65309,61,65310,62,65312,64,65316,68,65318,70,65319,71,65324,76,65329,81,65330,82,65333,85,65334,86,65335,87,65343,95,65346,98,65348,100,65350,102,65355,107,65357,109,65358,110,65361,113,65362,114,65364,116,65365,117,65367,119,65370,122,65371,123,65373,125],\"_default\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"cs\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"de\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"es\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"fr\":[65374,126,65306,58,65281,33,8216,96,8245,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"it\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ja\":[8211,45,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65292,44,65307,59],\"ko\":[8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pl\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"pt-BR\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"qps-ploc\":[160,32,8211,45,65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"ru\":[65374,126,65306,58,65281,33,8216,96,8217,96,8245,96,180,96,12494,47,305,105,921,73,1009,112,215,120,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"tr\":[160,32,8211,45,65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65288,40,65289,41,65292,44,65307,59,65311,63],\"zh-hans\":[65374,126,65306,58,65281,33,8245,96,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65288,40,65289,41],\"zh-hant\":[8211,45,65374,126,180,96,12494,47,1047,51,1073,54,1072,97,1040,65,1068,98,1042,66,1089,99,1057,67,1077,101,1045,69,1053,72,305,105,1050,75,921,73,1052,77,1086,111,1054,79,1009,112,1088,112,1056,80,1075,114,1058,84,215,120,1093,120,1061,88,1091,121,1059,89,65283,35,65307,59]}"
\ No newline at end of file
diff --git a/modules/charset/ambiguous/generate.go b/modules/charset/ambiguous/generate.go
new file mode 100644
index 000000000000..43cdb217a79a
--- /dev/null
+++ b/modules/charset/ambiguous/generate.go
@@ -0,0 +1,178 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "go/format"
+ "os"
+ "sort"
+ "text/template"
+ "unicode"
+
+ "code.gitea.io/gitea/modules/json"
+
+ "golang.org/x/text/unicode/rangetable"
+)
+
+// ambiguous.json provides a one to one mapping of ambiguous characters to other characters
+// See https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json
+
+type AmbiguousTable struct {
+ Confusable []rune
+ With []rune
+ Locale string
+ RangeTable *unicode.RangeTable
+}
+
+type RunePair struct {
+ Confusable rune
+ With rune
+}
+
+var verbose bool
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, `%s: Generate AmbiguousCharacter
+
+Usage: %[1]s [-v] [-o output.go] ambiguous.json
+`, os.Args[0])
+ flag.PrintDefaults()
+ }
+
+ output := ""
+ flag.BoolVar(&verbose, "v", false, "verbose output")
+ flag.StringVar(&output, "o", "ambiguous_gen.go", "file to output to")
+ flag.Parse()
+ input := flag.Arg(0)
+ if input == "" {
+ input = "ambiguous.json"
+ }
+
+ bs, err := os.ReadFile(input)
+ if err != nil {
+ fatalf("Unable to read: %s Err: %v", input, err)
+ }
+
+ var unwrapped string
+ if err := json.Unmarshal(bs, &unwrapped); err != nil {
+ fatalf("Unable to unwrap content in: %s Err: %v", input, err)
+ }
+
+ fromJSON := map[string][]uint32{}
+ if err := json.Unmarshal([]byte(unwrapped), &fromJSON); err != nil {
+ fatalf("Unable to unmarshal content in: %s Err: %v", input, err)
+ }
+
+ tables := make([]*AmbiguousTable, 0, len(fromJSON))
+ for locale, chars := range fromJSON {
+ table := &AmbiguousTable{Locale: locale}
+ table.Confusable = make([]rune, 0, len(chars)/2)
+ table.With = make([]rune, 0, len(chars)/2)
+ pairs := make([]RunePair, len(chars)/2)
+ for i := 0; i < len(chars); i += 2 {
+ pairs[i/2].Confusable, pairs[i/2].With = rune(chars[i]), rune(chars[i+1])
+ }
+ sort.Slice(pairs, func(i, j int) bool {
+ return pairs[i].Confusable < pairs[j].Confusable
+ })
+ for _, pair := range pairs {
+ table.Confusable = append(table.Confusable, pair.Confusable)
+ table.With = append(table.With, pair.With)
+ }
+ table.RangeTable = rangetable.New(table.Confusable...)
+ tables = append(tables, table)
+ }
+ sort.Slice(tables, func(i, j int) bool {
+ return tables[i].Locale < tables[j].Locale
+ })
+ data := map[string]interface{}{
+ "Tables": tables,
+ }
+
+ if err := runTemplate(generatorTemplate, output, &data); err != nil {
+ fatalf("Unable to run template: %v", err)
+ }
+}
+
+func runTemplate(t *template.Template, filename string, data interface{}) error {
+ buf := bytes.NewBuffer(nil)
+ if err := t.Execute(buf, data); err != nil {
+ return fmt.Errorf("unable to execute template: %w", err)
+ }
+ bs, err := format.Source(buf.Bytes())
+ if err != nil {
+ verbosef("Bad source:\n%s", buf.String())
+ return fmt.Errorf("unable to format source: %w", err)
+ }
+ file, err := os.Create(filename)
+ if err != nil {
+ return fmt.Errorf("failed to create file %s because %w", filename, err)
+ }
+ defer file.Close()
+ _, err = file.Write(bs)
+ if err != nil {
+ return fmt.Errorf("unable to write generated source: %w", err)
+ }
+ return nil
+}
+
+var generatorTemplate = template.Must(template.New("ambiguousTemplate").Parse(`// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import "unicode"
+
+// This file is generated from https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json
+
+// AmbiguousTable matches a confusable rune with its partner for the Locale
+type AmbiguousTable struct {
+ Confusable []rune
+ With []rune
+ Locale string
+ RangeTable *unicode.RangeTable
+}
+
+// AmbiguousCharacters provides a map by locale name to the confusable characters in that locale
+var AmbiguousCharacters = map[string]*AmbiguousTable{
+ {{range .Tables}}{{printf "%q:" .Locale}} {
+ Confusable: []rune{ {{range .Confusable}}{{.}},{{end}} },
+ With: []rune{ {{range .With}}{{.}},{{end}} },
+ Locale: {{printf "%q" .Locale}},
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {{range .RangeTable.R16 }} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}},
+ {{end}} },
+ R32: []unicode.Range32{
+ {{range .RangeTable.R32}} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}},
+ {{end}} },
+ LatinOffset: {{.RangeTable.LatinOffset}},
+ },
+ },
+ {{end}}
+}
+
+`))
+
+func logf(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, format+"\n", args...)
+}
+
+func verbosef(format string, args ...interface{}) {
+ if verbose {
+ logf(format, args...)
+ }
+}
+
+func fatalf(format string, args ...interface{}) {
+ logf("fatal: "+format+"\n", args...)
+ os.Exit(1)
+}
diff --git a/modules/charset/ambiguous_gen.go b/modules/charset/ambiguous_gen.go
new file mode 100644
index 000000000000..cc270affac52
--- /dev/null
+++ b/modules/charset/ambiguous_gen.go
@@ -0,0 +1,837 @@
+// This file is generated by modules/charset/ambiguous/generate.go DO NOT EDIT
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import "unicode"
+
+// This file is generated from https://github.com/hediet/vscode-unicode-data/blob/main/out/ambiguous.json
+
+// AmbiguousTable matches a confusable rune with its partner for the Locale
+type AmbiguousTable struct {
+ Confusable []rune
+ With []rune
+ Locale string
+ RangeTable *unicode.RangeTable
+}
+
+// AmbiguousCharacters provides a map by locale name to the confusable characters in that locale
+var AmbiguousCharacters = map[string]*AmbiguousTable{
+ "_common": {
+ Confusable: []rune{184, 383, 388, 397, 422, 423, 439, 444, 445, 448, 451, 540, 546, 547, 577, 593, 609, 611, 617, 618, 623, 651, 655, 660, 697, 699, 700, 701, 702, 706, 707, 708, 710, 712, 714, 715, 720, 727, 731, 732, 756, 760, 884, 890, 894, 895, 900, 913, 914, 917, 918, 919, 922, 924, 925, 927, 929, 932, 933, 935, 945, 947, 953, 957, 959, 961, 963, 965, 978, 988, 1000, 1010, 1011, 1017, 1018, 1029, 1030, 1032, 1109, 1110, 1112, 1121, 1140, 1141, 1198, 1199, 1211, 1213, 1216, 1231, 1248, 1281, 1292, 1307, 1308, 1309, 1357, 1359, 1365, 1370, 1373, 1377, 1379, 1382, 1392, 1400, 1404, 1405, 1409, 1412, 1413, 1417, 1472, 1475, 1493, 1496, 1497, 1503, 1505, 1523, 1549, 1575, 1607, 1632, 1633, 1637, 1639, 1643, 1645, 1726, 1729, 1748, 1749, 1776, 1777, 1781, 1783, 1793, 1794, 1795, 1796, 1984, 1994, 2036, 2037, 2042, 2307, 2406, 2429, 2534, 2538, 2541, 2662, 2663, 2666, 2691, 2790, 2819, 2848, 2918, 2920, 3046, 3074, 3174, 3202, 3302, 3330, 3360, 3430, 3437, 3458, 3664, 3792, 4125, 4160, 4327, 4351, 4608, 4816, 5024, 5025, 5026, 5029, 5033, 5034, 5035, 5036, 5038, 5043, 5047, 5051, 5053, 5056, 5058, 5059, 5070, 5071, 5074, 5076, 5077, 5081, 5082, 5086, 5087, 5090, 5094, 5095, 5102, 5107, 5108, 5120, 5167, 5171, 5176, 5194, 5196, 5229, 5231, 5234, 5261, 5290, 5311, 5441, 5500, 5501, 5511, 5551, 5556, 5573, 5598, 5610, 5616, 5623, 5741, 5742, 5760, 5810, 5815, 5825, 5836, 5845, 5846, 5868, 5869, 5941, 6147, 6153, 7428, 7439, 7441, 7452, 7456, 7457, 7458, 7462, 7555, 7564, 7837, 7935, 8125, 8126, 8127, 8128, 8175, 8189, 8190, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8208, 8209, 8210, 8218, 8219, 8228, 8232, 8233, 8239, 8242, 8249, 8250, 8257, 8259, 8260, 8270, 8275, 8282, 8287, 8450, 8458, 8459, 8460, 8461, 8462, 8464, 8465, 8466, 8467, 8469, 8473, 8474, 8475, 8476, 8477, 8484, 8488, 8490, 8492, 8493, 8494, 8495, 8496, 8497, 8499, 8500, 8505, 8509, 8517, 8518, 8519, 8520, 8521, 8544, 8548, 8553, 8556, 8557, 8558, 8559, 8560, 8564, 8569, 8572, 8573, 8574, 8722, 8725, 8726, 8727, 8739, 8744, 8746, 8758, 8764, 8868, 8897, 8899, 8959, 9075, 9076, 9082, 9213, 9585, 9587, 10088, 10089, 10094, 10095, 10098, 10099, 10100, 10101, 10133, 10134, 10187, 10189, 10201, 10539, 10540, 10741, 10744, 10745, 10799, 11397, 11406, 11410, 11412, 11416, 11418, 11422, 11423, 11426, 11427, 11428, 11429, 11430, 11432, 11436, 11450, 11462, 11466, 11468, 11472, 11474, 11576, 11577, 11599, 11601, 11604, 11605, 11613, 11840, 12034, 12035, 12295, 12308, 12309, 12339, 12448, 12755, 12756, 20022, 20031, 42192, 42193, 42194, 42195, 42196, 42198, 42199, 42201, 42202, 42204, 42205, 42207, 42208, 42209, 42210, 42211, 42214, 42215, 42218, 42219, 42220, 42222, 42224, 42226, 42227, 42228, 42232, 42233, 42237, 42239, 42510, 42564, 42567, 42719, 42731, 42735, 42801, 42842, 42858, 42862, 42872, 42889, 42892, 42904, 42905, 42911, 42923, 42930, 42931, 42932, 43826, 43829, 43837, 43847, 43848, 43854, 43858, 43866, 43893, 43905, 43907, 43923, 43945, 43946, 43951, 64422, 64423, 64424, 64425, 64426, 64427, 64428, 64429, 64830, 64831, 65072, 65101, 65102, 65103, 65112, 65128, 65165, 65166, 65257, 65258, 65259, 65260, 65282, 65284, 65285, 65286, 65287, 65290, 65291, 65293, 65294, 65295, 65296, 65297, 65298, 65299, 65300, 65301, 65302, 65303, 65304, 65305, 65308, 65309, 65310, 65312, 65313, 65314, 65315, 65316, 65317, 65318, 65319, 65320, 65321, 65322, 65323, 65324, 65325, 65326, 65327, 65328, 65329, 65330, 65331, 65332, 65333, 65334, 65335, 65336, 65337, 65338, 65339, 65340, 65341, 65342, 65343, 65344, 65345, 65346, 65347, 65348, 65349, 65350, 65351, 65352, 65353, 65354, 65355, 65356, 65357, 65358, 65359, 65360, 65361, 65362, 65363, 65364, 65365, 65366, 65367, 65368, 65369, 65370, 65371, 65372, 65373, 65512, 66178, 66182, 66183, 66186, 66192, 66194, 66197, 66198, 66199, 66203, 66208, 66209, 66210, 66213, 66219, 66224, 66225, 66226, 66228, 66255, 66293, 66305, 66306, 66313, 66321, 66325, 66327, 66330, 66335, 66336, 66338, 66564, 66581, 66587, 66592, 66604, 66621, 66632, 66740, 66754, 66766, 66770, 66794, 66806, 66835, 66838, 66840, 66844, 66845, 66853, 66854, 66855, 68176, 70864, 71430, 71434, 71438, 71439, 71840, 71842, 71843, 71844, 71846, 71849, 71852, 71854, 71855, 71858, 71861, 71864, 71867, 71868, 71872, 71873, 71874, 71875, 71876, 71878, 71880, 71882, 71884, 71893, 71894, 71895, 71896, 71900, 71904, 71909, 71910, 71913, 71916, 71919, 71922, 93960, 93962, 93974, 93992, 94005, 94010, 94011, 94015, 94016, 94018, 94019, 94033, 94034, 119060, 119149, 119302, 119309, 119311, 119314, 119315, 119318, 119338, 119350, 119351, 119354, 119355, 119808, 119809, 119810, 119811, 119812, 119813, 119814, 119815, 119816, 119817, 119818, 119819, 119820, 119821, 119822, 119823, 119824, 119825, 119826, 119827, 119828, 119829, 119830, 119831, 119832, 119833, 119834, 119835, 119836, 119837, 119838, 119839, 119840, 119841, 119842, 119843, 119844, 119845, 119847, 119848, 119849, 119850, 119851, 119852, 119853, 119854, 119855, 119856, 119857, 119858, 119859, 119860, 119861, 119862, 119863, 119864, 119865, 119866, 119867, 119868, 119869, 119870, 119871, 119872, 119873, 119874, 119875, 119876, 119877, 119878, 119879, 119880, 119881, 119882, 119883, 119884, 119885, 119886, 119887, 119888, 119889, 119890, 119891, 119892, 119894, 119895, 119896, 119897, 119899, 119900, 119901, 119902, 119903, 119904, 119905, 119906, 119907, 119908, 119909, 119910, 119911, 119912, 119913, 119914, 119915, 119916, 119917, 119918, 119919, 119920, 119921, 119922, 119923, 119924, 119925, 119926, 119927, 119928, 119929, 119930, 119931, 119932, 119933, 119934, 119935, 119936, 119937, 119938, 119939, 119940, 119941, 119942, 119943, 119944, 119945, 119946, 119947, 119948, 119949, 119951, 119952, 119953, 119954, 119955, 119956, 119957, 119958, 119959, 119960, 119961, 119962, 119963, 119964, 119966, 119967, 119970, 119973, 119974, 119977, 119978, 119979, 119980, 119982, 119983, 119984, 119985, 119986, 119987, 119988, 119989, 119990, 119991, 119992, 119993, 119995, 119997, 119998, 119999, 120000, 120001, 120003, 120005, 120006, 120007, 120008, 120009, 120010, 120011, 120012, 120013, 120014, 120015, 120016, 120017, 120018, 120019, 120020, 120021, 120022, 120023, 120024, 120025, 120026, 120027, 120028, 120029, 120030, 120031, 120032, 120033, 120034, 120035, 120036, 120037, 120038, 120039, 120040, 120041, 120042, 120043, 120044, 120045, 120046, 120047, 120048, 120049, 120050, 120051, 120052, 120053, 120055, 120056, 120057, 120058, 120059, 120060, 120061, 120062, 120063, 120064, 120065, 120066, 120067, 120068, 120069, 120071, 120072, 120073, 120074, 120077, 120078, 120079, 120080, 120081, 120082, 120083, 120084, 120086, 120087, 120088, 120089, 120090, 120091, 120092, 120094, 120095, 120096, 120097, 120098, 120099, 120100, 120101, 120102, 120103, 120104, 120105, 120107, 120108, 120109, 120110, 120111, 120112, 120113, 120114, 120115, 120116, 120117, 120118, 120119, 120120, 120121, 120123, 120124, 120125, 120126, 120128, 120129, 120130, 120131, 120132, 120134, 120138, 120139, 120140, 120141, 120142, 120143, 120144, 120146, 120147, 120148, 120149, 120150, 120151, 120152, 120153, 120154, 120155, 120156, 120157, 120159, 120160, 120161, 120162, 120163, 120164, 120165, 120166, 120167, 120168, 120169, 120170, 120171, 120172, 120173, 120174, 120175, 120176, 120177, 120178, 120179, 120180, 120181, 120182, 120183, 120184, 120185, 120186, 120187, 120188, 120189, 120190, 120191, 120192, 120193, 120194, 120195, 120196, 120197, 120198, 120199, 120200, 120201, 120202, 120203, 120204, 120205, 120206, 120207, 120208, 120209, 120211, 120212, 120213, 120214, 120215, 120216, 120217, 120218, 120219, 120220, 120221, 120222, 120223, 120224, 120225, 120226, 120227, 120228, 120229, 120230, 120231, 120232, 120233, 120234, 120235, 120236, 120237, 120238, 120239, 120240, 120241, 120242, 120243, 120244, 120245, 120246, 120247, 120248, 120249, 120250, 120251, 120252, 120253, 120254, 120255, 120256, 120257, 120258, 120259, 120260, 120261, 120263, 120264, 120265, 120266, 120267, 120268, 120269, 120270, 120271, 120272, 120273, 120274, 120275, 120276, 120277, 120278, 120279, 120280, 120281, 120282, 120283, 120284, 120285, 120286, 120287, 120288, 120289, 120290, 120291, 120292, 120293, 120294, 120295, 120296, 120297, 120298, 120299, 120300, 120301, 120302, 120303, 120304, 120305, 120306, 120307, 120308, 120309, 120310, 120311, 120312, 120313, 120315, 120316, 120317, 120318, 120319, 120320, 120321, 120322, 120323, 120324, 120325, 120326, 120327, 120328, 120329, 120330, 120331, 120332, 120333, 120334, 120335, 120336, 120337, 120338, 120339, 120340, 120341, 120342, 120343, 120344, 120345, 120346, 120347, 120348, 120349, 120350, 120351, 120352, 120353, 120354, 120355, 120356, 120357, 120358, 120359, 120360, 120361, 120362, 120363, 120364, 120365, 120367, 120368, 120369, 120370, 120371, 120372, 120373, 120374, 120375, 120376, 120377, 120378, 120379, 120380, 120381, 120382, 120383, 120384, 120385, 120386, 120387, 120388, 120389, 120390, 120391, 120392, 120393, 120394, 120395, 120396, 120397, 120398, 120399, 120400, 120401, 120402, 120403, 120404, 120405, 120406, 120407, 120408, 120409, 120410, 120411, 120412, 120413, 120414, 120415, 120416, 120417, 120419, 120420, 120421, 120422, 120423, 120424, 120425, 120426, 120427, 120428, 120429, 120430, 120431, 120432, 120433, 120434, 120435, 120436, 120437, 120438, 120439, 120440, 120441, 120442, 120443, 120444, 120445, 120446, 120447, 120448, 120449, 120450, 120451, 120452, 120453, 120454, 120455, 120456, 120457, 120458, 120459, 120460, 120461, 120462, 120463, 120464, 120465, 120466, 120467, 120468, 120469, 120471, 120472, 120473, 120474, 120475, 120476, 120477, 120478, 120479, 120480, 120481, 120482, 120483, 120484, 120488, 120489, 120492, 120493, 120494, 120496, 120497, 120499, 120500, 120502, 120504, 120507, 120508, 120510, 120514, 120516, 120522, 120526, 120528, 120530, 120532, 120534, 120544, 120546, 120547, 120550, 120551, 120552, 120554, 120555, 120557, 120558, 120560, 120562, 120565, 120566, 120568, 120572, 120574, 120580, 120584, 120586, 120588, 120590, 120592, 120602, 120604, 120605, 120608, 120609, 120610, 120612, 120613, 120615, 120616, 120618, 120620, 120623, 120624, 120626, 120630, 120632, 120638, 120642, 120644, 120646, 120648, 120650, 120660, 120662, 120663, 120666, 120667, 120668, 120670, 120671, 120673, 120674, 120676, 120678, 120681, 120682, 120684, 120688, 120690, 120696, 120700, 120702, 120704, 120706, 120708, 120718, 120720, 120721, 120724, 120725, 120726, 120728, 120729, 120731, 120732, 120734, 120736, 120739, 120740, 120742, 120746, 120748, 120754, 120758, 120760, 120762, 120764, 120766, 120776, 120778, 120782, 120783, 120784, 120785, 120786, 120787, 120788, 120789, 120790, 120791, 120792, 120793, 120794, 120795, 120796, 120797, 120798, 120799, 120800, 120801, 120802, 120803, 120804, 120805, 120806, 120807, 120808, 120809, 120810, 120811, 120812, 120813, 120814, 120815, 120816, 120817, 120818, 120819, 120820, 120821, 120822, 120823, 120824, 120825, 120826, 120827, 120828, 120829, 120830, 120831, 125127, 125131, 126464, 126500, 126564, 126592, 126596, 128844, 128872, 130032, 130033, 130034, 130035, 130036, 130037, 130038, 130039, 130040, 130041},
+ With: []rune{44, 102, 98, 103, 82, 50, 51, 53, 115, 73, 33, 51, 56, 56, 63, 97, 103, 121, 105, 105, 119, 117, 121, 63, 96, 96, 96, 96, 96, 60, 62, 94, 94, 96, 96, 96, 58, 45, 105, 126, 96, 58, 96, 105, 59, 74, 96, 65, 66, 69, 90, 72, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 89, 70, 50, 99, 106, 67, 77, 83, 73, 74, 115, 105, 106, 119, 86, 118, 89, 121, 104, 101, 73, 105, 51, 100, 71, 113, 87, 119, 85, 83, 79, 96, 96, 119, 113, 113, 104, 110, 110, 117, 103, 102, 111, 58, 108, 58, 108, 118, 96, 108, 111, 96, 44, 108, 111, 46, 108, 111, 86, 44, 42, 111, 111, 45, 111, 46, 73, 111, 86, 46, 46, 58, 58, 79, 108, 96, 96, 95, 58, 111, 63, 79, 56, 57, 111, 57, 56, 58, 111, 56, 79, 79, 57, 111, 111, 111, 111, 111, 111, 111, 111, 57, 111, 111, 111, 111, 111, 121, 111, 85, 79, 68, 82, 84, 105, 89, 65, 74, 69, 63, 87, 77, 72, 89, 71, 104, 90, 52, 98, 82, 87, 83, 86, 83, 76, 67, 80, 75, 100, 54, 71, 66, 61, 86, 62, 60, 96, 85, 80, 100, 98, 74, 76, 50, 120, 72, 120, 82, 98, 70, 65, 68, 68, 77, 66, 88, 120, 32, 60, 88, 73, 96, 75, 77, 58, 43, 47, 58, 58, 99, 111, 111, 117, 118, 119, 122, 114, 103, 121, 102, 121, 96, 105, 96, 126, 96, 96, 96, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 45, 45, 45, 44, 96, 46, 32, 32, 32, 96, 60, 62, 47, 45, 47, 42, 126, 58, 32, 67, 103, 72, 72, 72, 104, 73, 73, 76, 108, 78, 80, 81, 82, 82, 82, 90, 90, 75, 66, 67, 101, 101, 69, 70, 77, 111, 105, 121, 68, 100, 101, 105, 106, 73, 86, 88, 76, 67, 68, 77, 105, 118, 120, 73, 99, 100, 45, 47, 92, 42, 73, 118, 85, 58, 126, 84, 118, 85, 69, 105, 112, 97, 73, 47, 88, 40, 41, 60, 62, 40, 41, 123, 125, 43, 45, 47, 92, 84, 120, 120, 92, 47, 92, 120, 114, 72, 73, 75, 77, 78, 79, 111, 80, 112, 67, 99, 84, 89, 88, 45, 47, 57, 51, 76, 54, 86, 69, 73, 33, 79, 81, 88, 61, 92, 47, 79, 40, 41, 47, 61, 47, 92, 92, 47, 66, 80, 100, 68, 84, 71, 75, 74, 67, 90, 70, 77, 78, 76, 83, 82, 86, 72, 87, 88, 89, 65, 69, 73, 79, 85, 46, 44, 58, 61, 46, 50, 105, 86, 63, 50, 115, 50, 51, 57, 38, 58, 96, 70, 102, 117, 51, 74, 88, 66, 101, 102, 111, 114, 114, 117, 117, 121, 105, 114, 119, 122, 118, 115, 99, 111, 111, 111, 111, 111, 111, 111, 111, 40, 41, 58, 95, 95, 95, 45, 92, 108, 108, 111, 111, 111, 111, 34, 36, 37, 38, 96, 42, 43, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 60, 61, 62, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 73, 66, 69, 70, 124, 88, 79, 80, 83, 84, 43, 65, 66, 67, 70, 79, 77, 84, 89, 88, 72, 90, 66, 67, 124, 77, 84, 88, 56, 42, 108, 88, 79, 67, 76, 83, 111, 99, 115, 82, 79, 85, 55, 111, 117, 78, 79, 75, 67, 86, 70, 76, 88, 46, 79, 118, 119, 119, 119, 86, 70, 76, 89, 69, 90, 57, 69, 52, 76, 79, 85, 53, 84, 118, 115, 70, 105, 122, 55, 111, 51, 57, 54, 57, 111, 117, 121, 79, 90, 87, 67, 88, 87, 67, 86, 84, 76, 73, 82, 83, 51, 62, 65, 85, 89, 96, 96, 123, 46, 51, 86, 92, 55, 70, 82, 76, 60, 62, 47, 92, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 67, 68, 71, 74, 75, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 102, 104, 105, 106, 107, 108, 110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 68, 69, 70, 71, 74, 75, 76, 77, 78, 79, 80, 81, 83, 84, 85, 86, 87, 88, 89, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 68, 69, 70, 71, 73, 74, 75, 76, 77, 79, 83, 84, 85, 86, 87, 88, 89, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 73, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 105, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 65, 66, 69, 90, 72, 73, 75, 77, 78, 79, 80, 84, 89, 88, 97, 121, 105, 118, 111, 112, 111, 117, 112, 70, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57, 108, 56, 108, 111, 111, 108, 111, 67, 84, 79, 73, 50, 51, 52, 53, 54, 55, 56, 57},
+ Locale: "_common",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 184, Hi: 383, Stride: 199},
+ {Lo: 388, Hi: 397, Stride: 9},
+ {Lo: 422, Hi: 423, Stride: 1},
+ {Lo: 439, Hi: 444, Stride: 5},
+ {Lo: 445, Hi: 451, Stride: 3},
+ {Lo: 540, Hi: 546, Stride: 6},
+ {Lo: 547, Hi: 577, Stride: 30},
+ {Lo: 593, Hi: 609, Stride: 16},
+ {Lo: 611, Hi: 617, Stride: 6},
+ {Lo: 618, Hi: 623, Stride: 5},
+ {Lo: 651, Hi: 655, Stride: 4},
+ {Lo: 660, Hi: 697, Stride: 37},
+ {Lo: 699, Hi: 702, Stride: 1},
+ {Lo: 706, Hi: 708, Stride: 1},
+ {Lo: 710, Hi: 714, Stride: 2},
+ {Lo: 715, Hi: 720, Stride: 5},
+ {Lo: 727, Hi: 731, Stride: 4},
+ {Lo: 732, Hi: 756, Stride: 24},
+ {Lo: 760, Hi: 884, Stride: 124},
+ {Lo: 890, Hi: 894, Stride: 4},
+ {Lo: 895, Hi: 900, Stride: 5},
+ {Lo: 913, Hi: 914, Stride: 1},
+ {Lo: 917, Hi: 919, Stride: 1},
+ {Lo: 922, Hi: 924, Stride: 2},
+ {Lo: 925, Hi: 929, Stride: 2},
+ {Lo: 932, Hi: 933, Stride: 1},
+ {Lo: 935, Hi: 945, Stride: 10},
+ {Lo: 947, Hi: 953, Stride: 6},
+ {Lo: 957, Hi: 965, Stride: 2},
+ {Lo: 978, Hi: 988, Stride: 10},
+ {Lo: 1000, Hi: 1010, Stride: 10},
+ {Lo: 1011, Hi: 1017, Stride: 6},
+ {Lo: 1018, Hi: 1029, Stride: 11},
+ {Lo: 1030, Hi: 1032, Stride: 2},
+ {Lo: 1109, Hi: 1110, Stride: 1},
+ {Lo: 1112, Hi: 1121, Stride: 9},
+ {Lo: 1140, Hi: 1141, Stride: 1},
+ {Lo: 1198, Hi: 1199, Stride: 1},
+ {Lo: 1211, Hi: 1213, Stride: 2},
+ {Lo: 1216, Hi: 1231, Stride: 15},
+ {Lo: 1248, Hi: 1281, Stride: 33},
+ {Lo: 1292, Hi: 1307, Stride: 15},
+ {Lo: 1308, Hi: 1309, Stride: 1},
+ {Lo: 1357, Hi: 1359, Stride: 2},
+ {Lo: 1365, Hi: 1370, Stride: 5},
+ {Lo: 1373, Hi: 1377, Stride: 4},
+ {Lo: 1379, Hi: 1382, Stride: 3},
+ {Lo: 1392, Hi: 1400, Stride: 8},
+ {Lo: 1404, Hi: 1405, Stride: 1},
+ {Lo: 1409, Hi: 1412, Stride: 3},
+ {Lo: 1413, Hi: 1417, Stride: 4},
+ {Lo: 1472, Hi: 1475, Stride: 3},
+ {Lo: 1493, Hi: 1496, Stride: 3},
+ {Lo: 1497, Hi: 1503, Stride: 6},
+ {Lo: 1505, Hi: 1523, Stride: 18},
+ {Lo: 1549, Hi: 1575, Stride: 26},
+ {Lo: 1607, Hi: 1632, Stride: 25},
+ {Lo: 1633, Hi: 1637, Stride: 4},
+ {Lo: 1639, Hi: 1643, Stride: 4},
+ {Lo: 1645, Hi: 1726, Stride: 81},
+ {Lo: 1729, Hi: 1748, Stride: 19},
+ {Lo: 1749, Hi: 1776, Stride: 27},
+ {Lo: 1777, Hi: 1781, Stride: 4},
+ {Lo: 1783, Hi: 1793, Stride: 10},
+ {Lo: 1794, Hi: 1796, Stride: 1},
+ {Lo: 1984, Hi: 1994, Stride: 10},
+ {Lo: 2036, Hi: 2037, Stride: 1},
+ {Lo: 2042, Hi: 2307, Stride: 265},
+ {Lo: 2406, Hi: 2429, Stride: 23},
+ {Lo: 2534, Hi: 2538, Stride: 4},
+ {Lo: 2541, Hi: 2662, Stride: 121},
+ {Lo: 2663, Hi: 2666, Stride: 3},
+ {Lo: 2691, Hi: 2790, Stride: 99},
+ {Lo: 2819, Hi: 2848, Stride: 29},
+ {Lo: 2918, Hi: 2920, Stride: 2},
+ {Lo: 3046, Hi: 3074, Stride: 28},
+ {Lo: 3174, Hi: 3202, Stride: 28},
+ {Lo: 3302, Hi: 3330, Stride: 28},
+ {Lo: 3360, Hi: 3430, Stride: 70},
+ {Lo: 3437, Hi: 3458, Stride: 21},
+ {Lo: 3664, Hi: 3792, Stride: 128},
+ {Lo: 4125, Hi: 4160, Stride: 35},
+ {Lo: 4327, Hi: 4351, Stride: 24},
+ {Lo: 4608, Hi: 5024, Stride: 208},
+ {Lo: 5025, Hi: 5026, Stride: 1},
+ {Lo: 5029, Hi: 5033, Stride: 4},
+ {Lo: 5034, Hi: 5036, Stride: 1},
+ {Lo: 5038, Hi: 5043, Stride: 5},
+ {Lo: 5047, Hi: 5051, Stride: 4},
+ {Lo: 5053, Hi: 5056, Stride: 3},
+ {Lo: 5058, Hi: 5059, Stride: 1},
+ {Lo: 5070, Hi: 5071, Stride: 1},
+ {Lo: 5074, Hi: 5076, Stride: 2},
+ {Lo: 5077, Hi: 5081, Stride: 4},
+ {Lo: 5082, Hi: 5086, Stride: 4},
+ {Lo: 5087, Hi: 5090, Stride: 3},
+ {Lo: 5094, Hi: 5095, Stride: 1},
+ {Lo: 5102, Hi: 5107, Stride: 5},
+ {Lo: 5108, Hi: 5120, Stride: 12},
+ {Lo: 5167, Hi: 5171, Stride: 4},
+ {Lo: 5176, Hi: 5194, Stride: 18},
+ {Lo: 5196, Hi: 5229, Stride: 33},
+ {Lo: 5231, Hi: 5234, Stride: 3},
+ {Lo: 5261, Hi: 5290, Stride: 29},
+ {Lo: 5311, Hi: 5441, Stride: 130},
+ {Lo: 5500, Hi: 5501, Stride: 1},
+ {Lo: 5511, Hi: 5551, Stride: 40},
+ {Lo: 5556, Hi: 5573, Stride: 17},
+ {Lo: 5598, Hi: 5610, Stride: 12},
+ {Lo: 5616, Hi: 5623, Stride: 7},
+ {Lo: 5741, Hi: 5742, Stride: 1},
+ {Lo: 5760, Hi: 5810, Stride: 50},
+ {Lo: 5815, Hi: 5825, Stride: 10},
+ {Lo: 5836, Hi: 5845, Stride: 9},
+ {Lo: 5846, Hi: 5868, Stride: 22},
+ {Lo: 5869, Hi: 5941, Stride: 72},
+ {Lo: 6147, Hi: 6153, Stride: 6},
+ {Lo: 7428, Hi: 7439, Stride: 11},
+ {Lo: 7441, Hi: 7452, Stride: 11},
+ {Lo: 7456, Hi: 7458, Stride: 1},
+ {Lo: 7462, Hi: 7555, Stride: 93},
+ {Lo: 7564, Hi: 7837, Stride: 273},
+ {Lo: 7935, Hi: 8125, Stride: 190},
+ {Lo: 8126, Hi: 8128, Stride: 1},
+ {Lo: 8175, Hi: 8189, Stride: 14},
+ {Lo: 8190, Hi: 8192, Stride: 2},
+ {Lo: 8193, Hi: 8202, Stride: 1},
+ {Lo: 8208, Hi: 8210, Stride: 1},
+ {Lo: 8218, Hi: 8219, Stride: 1},
+ {Lo: 8228, Hi: 8232, Stride: 4},
+ {Lo: 8233, Hi: 8239, Stride: 6},
+ {Lo: 8242, Hi: 8249, Stride: 7},
+ {Lo: 8250, Hi: 8257, Stride: 7},
+ {Lo: 8259, Hi: 8260, Stride: 1},
+ {Lo: 8270, Hi: 8275, Stride: 5},
+ {Lo: 8282, Hi: 8287, Stride: 5},
+ {Lo: 8450, Hi: 8458, Stride: 8},
+ {Lo: 8459, Hi: 8462, Stride: 1},
+ {Lo: 8464, Hi: 8467, Stride: 1},
+ {Lo: 8469, Hi: 8473, Stride: 4},
+ {Lo: 8474, Hi: 8477, Stride: 1},
+ {Lo: 8484, Hi: 8488, Stride: 4},
+ {Lo: 8490, Hi: 8492, Stride: 2},
+ {Lo: 8493, Hi: 8497, Stride: 1},
+ {Lo: 8499, Hi: 8500, Stride: 1},
+ {Lo: 8505, Hi: 8509, Stride: 4},
+ {Lo: 8517, Hi: 8521, Stride: 1},
+ {Lo: 8544, Hi: 8548, Stride: 4},
+ {Lo: 8553, Hi: 8556, Stride: 3},
+ {Lo: 8557, Hi: 8560, Stride: 1},
+ {Lo: 8564, Hi: 8569, Stride: 5},
+ {Lo: 8572, Hi: 8574, Stride: 1},
+ {Lo: 8722, Hi: 8725, Stride: 3},
+ {Lo: 8726, Hi: 8727, Stride: 1},
+ {Lo: 8739, Hi: 8744, Stride: 5},
+ {Lo: 8746, Hi: 8758, Stride: 12},
+ {Lo: 8764, Hi: 8868, Stride: 104},
+ {Lo: 8897, Hi: 8899, Stride: 2},
+ {Lo: 8959, Hi: 9075, Stride: 116},
+ {Lo: 9076, Hi: 9082, Stride: 6},
+ {Lo: 9213, Hi: 9585, Stride: 372},
+ {Lo: 9587, Hi: 10088, Stride: 501},
+ {Lo: 10089, Hi: 10094, Stride: 5},
+ {Lo: 10095, Hi: 10098, Stride: 3},
+ {Lo: 10099, Hi: 10101, Stride: 1},
+ {Lo: 10133, Hi: 10134, Stride: 1},
+ {Lo: 10187, Hi: 10189, Stride: 2},
+ {Lo: 10201, Hi: 10539, Stride: 338},
+ {Lo: 10540, Hi: 10741, Stride: 201},
+ {Lo: 10744, Hi: 10745, Stride: 1},
+ {Lo: 10799, Hi: 11397, Stride: 598},
+ {Lo: 11406, Hi: 11410, Stride: 4},
+ {Lo: 11412, Hi: 11416, Stride: 4},
+ {Lo: 11418, Hi: 11422, Stride: 4},
+ {Lo: 11423, Hi: 11426, Stride: 3},
+ {Lo: 11427, Hi: 11430, Stride: 1},
+ {Lo: 11432, Hi: 11436, Stride: 4},
+ {Lo: 11450, Hi: 11462, Stride: 12},
+ {Lo: 11466, Hi: 11468, Stride: 2},
+ {Lo: 11472, Hi: 11474, Stride: 2},
+ {Lo: 11576, Hi: 11577, Stride: 1},
+ {Lo: 11599, Hi: 11601, Stride: 2},
+ {Lo: 11604, Hi: 11605, Stride: 1},
+ {Lo: 11613, Hi: 11840, Stride: 227},
+ {Lo: 12034, Hi: 12035, Stride: 1},
+ {Lo: 12295, Hi: 12308, Stride: 13},
+ {Lo: 12309, Hi: 12339, Stride: 30},
+ {Lo: 12448, Hi: 12755, Stride: 307},
+ {Lo: 12756, Hi: 20022, Stride: 7266},
+ {Lo: 20031, Hi: 42192, Stride: 22161},
+ {Lo: 42193, Hi: 42196, Stride: 1},
+ {Lo: 42198, Hi: 42199, Stride: 1},
+ {Lo: 42201, Hi: 42202, Stride: 1},
+ {Lo: 42204, Hi: 42205, Stride: 1},
+ {Lo: 42207, Hi: 42211, Stride: 1},
+ {Lo: 42214, Hi: 42215, Stride: 1},
+ {Lo: 42218, Hi: 42220, Stride: 1},
+ {Lo: 42222, Hi: 42226, Stride: 2},
+ {Lo: 42227, Hi: 42228, Stride: 1},
+ {Lo: 42232, Hi: 42233, Stride: 1},
+ {Lo: 42237, Hi: 42239, Stride: 2},
+ {Lo: 42510, Hi: 42564, Stride: 54},
+ {Lo: 42567, Hi: 42719, Stride: 152},
+ {Lo: 42731, Hi: 42735, Stride: 4},
+ {Lo: 42801, Hi: 42842, Stride: 41},
+ {Lo: 42858, Hi: 42862, Stride: 4},
+ {Lo: 42872, Hi: 42889, Stride: 17},
+ {Lo: 42892, Hi: 42904, Stride: 12},
+ {Lo: 42905, Hi: 42911, Stride: 6},
+ {Lo: 42923, Hi: 42930, Stride: 7},
+ {Lo: 42931, Hi: 42932, Stride: 1},
+ {Lo: 43826, Hi: 43829, Stride: 3},
+ {Lo: 43837, Hi: 43847, Stride: 10},
+ {Lo: 43848, Hi: 43854, Stride: 6},
+ {Lo: 43858, Hi: 43866, Stride: 8},
+ {Lo: 43893, Hi: 43905, Stride: 12},
+ {Lo: 43907, Hi: 43923, Stride: 16},
+ {Lo: 43945, Hi: 43946, Stride: 1},
+ {Lo: 43951, Hi: 64422, Stride: 20471},
+ {Lo: 64423, Hi: 64429, Stride: 1},
+ {Lo: 64830, Hi: 64831, Stride: 1},
+ {Lo: 65072, Hi: 65101, Stride: 29},
+ {Lo: 65102, Hi: 65103, Stride: 1},
+ {Lo: 65112, Hi: 65128, Stride: 16},
+ {Lo: 65165, Hi: 65166, Stride: 1},
+ {Lo: 65257, Hi: 65260, Stride: 1},
+ {Lo: 65282, Hi: 65284, Stride: 2},
+ {Lo: 65285, Hi: 65287, Stride: 1},
+ {Lo: 65290, Hi: 65291, Stride: 1},
+ {Lo: 65293, Hi: 65305, Stride: 1},
+ {Lo: 65308, Hi: 65310, Stride: 1},
+ {Lo: 65312, Hi: 65373, Stride: 1},
+ {Lo: 65512, Hi: 65512, Stride: 1},
+ },
+ R32: []unicode.Range32{
+ {Lo: 66178, Hi: 66182, Stride: 4},
+ {Lo: 66183, Hi: 66186, Stride: 3},
+ {Lo: 66192, Hi: 66194, Stride: 2},
+ {Lo: 66197, Hi: 66199, Stride: 1},
+ {Lo: 66203, Hi: 66208, Stride: 5},
+ {Lo: 66209, Hi: 66210, Stride: 1},
+ {Lo: 66213, Hi: 66219, Stride: 6},
+ {Lo: 66224, Hi: 66226, Stride: 1},
+ {Lo: 66228, Hi: 66255, Stride: 27},
+ {Lo: 66293, Hi: 66305, Stride: 12},
+ {Lo: 66306, Hi: 66313, Stride: 7},
+ {Lo: 66321, Hi: 66325, Stride: 4},
+ {Lo: 66327, Hi: 66330, Stride: 3},
+ {Lo: 66335, Hi: 66336, Stride: 1},
+ {Lo: 66338, Hi: 66564, Stride: 226},
+ {Lo: 66581, Hi: 66587, Stride: 6},
+ {Lo: 66592, Hi: 66604, Stride: 12},
+ {Lo: 66621, Hi: 66632, Stride: 11},
+ {Lo: 66740, Hi: 66754, Stride: 14},
+ {Lo: 66766, Hi: 66770, Stride: 4},
+ {Lo: 66794, Hi: 66806, Stride: 12},
+ {Lo: 66835, Hi: 66838, Stride: 3},
+ {Lo: 66840, Hi: 66844, Stride: 4},
+ {Lo: 66845, Hi: 66853, Stride: 8},
+ {Lo: 66854, Hi: 66855, Stride: 1},
+ {Lo: 68176, Hi: 70864, Stride: 2688},
+ {Lo: 71430, Hi: 71438, Stride: 4},
+ {Lo: 71439, Hi: 71840, Stride: 401},
+ {Lo: 71842, Hi: 71844, Stride: 1},
+ {Lo: 71846, Hi: 71852, Stride: 3},
+ {Lo: 71854, Hi: 71855, Stride: 1},
+ {Lo: 71858, Hi: 71867, Stride: 3},
+ {Lo: 71868, Hi: 71872, Stride: 4},
+ {Lo: 71873, Hi: 71876, Stride: 1},
+ {Lo: 71878, Hi: 71884, Stride: 2},
+ {Lo: 71893, Hi: 71896, Stride: 1},
+ {Lo: 71900, Hi: 71904, Stride: 4},
+ {Lo: 71909, Hi: 71910, Stride: 1},
+ {Lo: 71913, Hi: 71922, Stride: 3},
+ {Lo: 93960, Hi: 93962, Stride: 2},
+ {Lo: 93974, Hi: 93992, Stride: 18},
+ {Lo: 94005, Hi: 94010, Stride: 5},
+ {Lo: 94011, Hi: 94015, Stride: 4},
+ {Lo: 94016, Hi: 94018, Stride: 2},
+ {Lo: 94019, Hi: 94033, Stride: 14},
+ {Lo: 94034, Hi: 119060, Stride: 25026},
+ {Lo: 119149, Hi: 119302, Stride: 153},
+ {Lo: 119309, Hi: 119311, Stride: 2},
+ {Lo: 119314, Hi: 119315, Stride: 1},
+ {Lo: 119318, Hi: 119338, Stride: 20},
+ {Lo: 119350, Hi: 119351, Stride: 1},
+ {Lo: 119354, Hi: 119355, Stride: 1},
+ {Lo: 119808, Hi: 119845, Stride: 1},
+ {Lo: 119847, Hi: 119892, Stride: 1},
+ {Lo: 119894, Hi: 119897, Stride: 1},
+ {Lo: 119899, Hi: 119949, Stride: 1},
+ {Lo: 119951, Hi: 119964, Stride: 1},
+ {Lo: 119966, Hi: 119967, Stride: 1},
+ {Lo: 119970, Hi: 119973, Stride: 3},
+ {Lo: 119974, Hi: 119977, Stride: 3},
+ {Lo: 119978, Hi: 119980, Stride: 1},
+ {Lo: 119982, Hi: 119993, Stride: 1},
+ {Lo: 119995, Hi: 119997, Stride: 2},
+ {Lo: 119998, Hi: 120001, Stride: 1},
+ {Lo: 120003, Hi: 120005, Stride: 2},
+ {Lo: 120006, Hi: 120053, Stride: 1},
+ {Lo: 120055, Hi: 120069, Stride: 1},
+ {Lo: 120071, Hi: 120074, Stride: 1},
+ {Lo: 120077, Hi: 120084, Stride: 1},
+ {Lo: 120086, Hi: 120092, Stride: 1},
+ {Lo: 120094, Hi: 120105, Stride: 1},
+ {Lo: 120107, Hi: 120121, Stride: 1},
+ {Lo: 120123, Hi: 120126, Stride: 1},
+ {Lo: 120128, Hi: 120132, Stride: 1},
+ {Lo: 120134, Hi: 120138, Stride: 4},
+ {Lo: 120139, Hi: 120144, Stride: 1},
+ {Lo: 120146, Hi: 120157, Stride: 1},
+ {Lo: 120159, Hi: 120209, Stride: 1},
+ {Lo: 120211, Hi: 120261, Stride: 1},
+ {Lo: 120263, Hi: 120313, Stride: 1},
+ {Lo: 120315, Hi: 120365, Stride: 1},
+ {Lo: 120367, Hi: 120417, Stride: 1},
+ {Lo: 120419, Hi: 120469, Stride: 1},
+ {Lo: 120471, Hi: 120484, Stride: 1},
+ {Lo: 120488, Hi: 120489, Stride: 1},
+ {Lo: 120492, Hi: 120494, Stride: 1},
+ {Lo: 120496, Hi: 120497, Stride: 1},
+ {Lo: 120499, Hi: 120500, Stride: 1},
+ {Lo: 120502, Hi: 120504, Stride: 2},
+ {Lo: 120507, Hi: 120508, Stride: 1},
+ {Lo: 120510, Hi: 120514, Stride: 4},
+ {Lo: 120516, Hi: 120522, Stride: 6},
+ {Lo: 120526, Hi: 120534, Stride: 2},
+ {Lo: 120544, Hi: 120546, Stride: 2},
+ {Lo: 120547, Hi: 120550, Stride: 3},
+ {Lo: 120551, Hi: 120552, Stride: 1},
+ {Lo: 120554, Hi: 120555, Stride: 1},
+ {Lo: 120557, Hi: 120558, Stride: 1},
+ {Lo: 120560, Hi: 120562, Stride: 2},
+ {Lo: 120565, Hi: 120566, Stride: 1},
+ {Lo: 120568, Hi: 120572, Stride: 4},
+ {Lo: 120574, Hi: 120580, Stride: 6},
+ {Lo: 120584, Hi: 120592, Stride: 2},
+ {Lo: 120602, Hi: 120604, Stride: 2},
+ {Lo: 120605, Hi: 120608, Stride: 3},
+ {Lo: 120609, Hi: 120610, Stride: 1},
+ {Lo: 120612, Hi: 120613, Stride: 1},
+ {Lo: 120615, Hi: 120616, Stride: 1},
+ {Lo: 120618, Hi: 120620, Stride: 2},
+ {Lo: 120623, Hi: 120624, Stride: 1},
+ {Lo: 120626, Hi: 120630, Stride: 4},
+ {Lo: 120632, Hi: 120638, Stride: 6},
+ {Lo: 120642, Hi: 120650, Stride: 2},
+ {Lo: 120660, Hi: 120662, Stride: 2},
+ {Lo: 120663, Hi: 120666, Stride: 3},
+ {Lo: 120667, Hi: 120668, Stride: 1},
+ {Lo: 120670, Hi: 120671, Stride: 1},
+ {Lo: 120673, Hi: 120674, Stride: 1},
+ {Lo: 120676, Hi: 120678, Stride: 2},
+ {Lo: 120681, Hi: 120682, Stride: 1},
+ {Lo: 120684, Hi: 120688, Stride: 4},
+ {Lo: 120690, Hi: 120696, Stride: 6},
+ {Lo: 120700, Hi: 120708, Stride: 2},
+ {Lo: 120718, Hi: 120720, Stride: 2},
+ {Lo: 120721, Hi: 120724, Stride: 3},
+ {Lo: 120725, Hi: 120726, Stride: 1},
+ {Lo: 120728, Hi: 120729, Stride: 1},
+ {Lo: 120731, Hi: 120732, Stride: 1},
+ {Lo: 120734, Hi: 120736, Stride: 2},
+ {Lo: 120739, Hi: 120740, Stride: 1},
+ {Lo: 120742, Hi: 120746, Stride: 4},
+ {Lo: 120748, Hi: 120754, Stride: 6},
+ {Lo: 120758, Hi: 120766, Stride: 2},
+ {Lo: 120776, Hi: 120778, Stride: 2},
+ {Lo: 120782, Hi: 120831, Stride: 1},
+ {Lo: 125127, Hi: 125131, Stride: 4},
+ {Lo: 126464, Hi: 126500, Stride: 36},
+ {Lo: 126564, Hi: 126592, Stride: 28},
+ {Lo: 126596, Hi: 128844, Stride: 2248},
+ {Lo: 128872, Hi: 130032, Stride: 1160},
+ {Lo: 130033, Hi: 130041, Stride: 1},
+ },
+ LatinOffset: 0,
+ },
+ },
+ "_default": {
+ Confusable: []rune{160, 180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{32, 96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "_default",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 160, Hi: 180, Stride: 20},
+ {Lo: 215, Hi: 305, Stride: 90},
+ {Lo: 921, Hi: 1009, Stride: 88},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8216, Stride: 5},
+ {Lo: 8217, Hi: 8245, Stride: 28},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "cs": {
+ Confusable: []rune{180, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "cs",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 305, Stride: 125},
+ {Lo: 921, Hi: 1009, Stride: 88},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8216, Hi: 8217, Stride: 1},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65288, Hi: 65289, Stride: 1},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65311, Stride: 4},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 0,
+ },
+ },
+ "de": {
+ Confusable: []rune{180, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "de",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 305, Stride: 125},
+ {Lo: 921, Hi: 1009, Stride: 88},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8216, Hi: 8217, Stride: 1},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65288, Hi: 65289, Stride: 1},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65311, Stride: 4},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 0,
+ },
+ },
+ "es": {
+ Confusable: []rune{180, 215, 305, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 120, 105, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "es",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 1009, Stride: 704},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8245, Stride: 34},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "fr": {
+ Confusable: []rune{215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "fr",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 215, Hi: 305, Stride: 90},
+ {Lo: 921, Hi: 1009, Stride: 88},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8216, Hi: 8245, Stride: 29},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 0,
+ },
+ },
+ "it": {
+ Confusable: []rune{160, 180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{32, 96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "it",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 160, Hi: 180, Stride: 20},
+ {Lo: 215, Hi: 305, Stride: 90},
+ {Lo: 921, Hi: 1009, Stride: 88},
+ {Lo: 1040, Hi: 1042, Stride: 2},
+ {Lo: 1045, Hi: 1047, Stride: 2},
+ {Lo: 1050, Hi: 1052, Stride: 2},
+ {Lo: 1053, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8216, Stride: 5},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65288, Hi: 65289, Stride: 1},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65311, Stride: 4},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "ja": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 65281, 65283, 65292, 65306, 65307},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 33, 35, 44, 58, 59},
+ Locale: "ja",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8216, Stride: 5},
+ {Lo: 8217, Hi: 8245, Stride: 28},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65307, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "ko": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "ko",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8245, Stride: 34},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "pl": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "pl",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8216, Hi: 8217, Stride: 1},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65288, Hi: 65289, Stride: 1},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65311, Stride: 4},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "pt-BR": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "pt-BR",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8216, Hi: 8217, Stride: 1},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65283, Stride: 2},
+ {Lo: 65288, Hi: 65289, Stride: 1},
+ {Lo: 65292, Hi: 65306, Stride: 14},
+ {Lo: 65307, Hi: 65311, Stride: 4},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "qps-ploc": {
+ Confusable: []rune{160, 180, 215, 305, 921, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{32, 96, 120, 105, 73, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "qps-ploc",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 160, Hi: 180, Stride: 20},
+ {Lo: 215, Hi: 305, Stride: 90},
+ {Lo: 921, Hi: 1040, Stride: 119},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8216, Stride: 5},
+ {Lo: 8217, Hi: 8245, Stride: 28},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "ru": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 8216, 8217, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{96, 120, 105, 73, 112, 96, 96, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "ru",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 8216, Stride: 7207},
+ {Lo: 8217, Hi: 8245, Stride: 28},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "tr": {
+ Confusable: []rune{160, 180, 215, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 8245, 12494, 65281, 65283, 65288, 65289, 65292, 65306, 65307, 65311, 65374},
+ With: []rune{32, 96, 120, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 96, 47, 33, 35, 40, 41, 44, 58, 59, 63, 126},
+ Locale: "tr",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 160, Hi: 180, Stride: 20},
+ {Lo: 215, Hi: 921, Stride: 706},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 8245, Stride: 34},
+ {Lo: 12494, Hi: 65281, Stride: 52787},
+ {Lo: 65283, Hi: 65288, Stride: 5},
+ {Lo: 65289, Hi: 65292, Stride: 3},
+ {Lo: 65306, Hi: 65307, Stride: 1},
+ {Lo: 65311, Hi: 65374, Stride: 63},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "zh-hans": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8245, 12494, 65281, 65288, 65289, 65306, 65374},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 96, 47, 33, 40, 41, 58, 126},
+ Locale: "zh-hans",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8245, Hi: 12494, Stride: 4249},
+ {Lo: 65281, Hi: 65288, Stride: 7},
+ {Lo: 65289, Hi: 65306, Stride: 17},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+ "zh-hant": {
+ Confusable: []rune{180, 215, 305, 921, 1009, 1040, 1042, 1045, 1047, 1050, 1052, 1053, 1054, 1056, 1057, 1058, 1059, 1061, 1068, 1072, 1073, 1075, 1077, 1086, 1088, 1089, 1091, 1093, 8211, 12494, 65283, 65307, 65374},
+ With: []rune{96, 120, 105, 73, 112, 65, 66, 69, 51, 75, 77, 72, 79, 80, 67, 84, 89, 88, 98, 97, 54, 114, 101, 111, 112, 99, 121, 120, 45, 47, 35, 59, 126},
+ Locale: "zh-hant",
+ RangeTable: &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 180, Hi: 215, Stride: 35},
+ {Lo: 305, Hi: 921, Stride: 616},
+ {Lo: 1009, Hi: 1040, Stride: 31},
+ {Lo: 1042, Hi: 1045, Stride: 3},
+ {Lo: 1047, Hi: 1050, Stride: 3},
+ {Lo: 1052, Hi: 1054, Stride: 1},
+ {Lo: 1056, Hi: 1059, Stride: 1},
+ {Lo: 1061, Hi: 1068, Stride: 7},
+ {Lo: 1072, Hi: 1073, Stride: 1},
+ {Lo: 1075, Hi: 1077, Stride: 2},
+ {Lo: 1086, Hi: 1088, Stride: 2},
+ {Lo: 1089, Hi: 1093, Stride: 2},
+ {Lo: 8211, Hi: 12494, Stride: 4283},
+ {Lo: 65283, Hi: 65307, Stride: 24},
+ {Lo: 65374, Hi: 65374, Stride: 1},
+ },
+ R32: []unicode.Range32{},
+ LatinOffset: 1,
+ },
+ },
+}
diff --git a/modules/charset/ambiguous_gen_test.go b/modules/charset/ambiguous_gen_test.go
new file mode 100644
index 000000000000..bd64e1c5b1c9
--- /dev/null
+++ b/modules/charset/ambiguous_gen_test.go
@@ -0,0 +1,32 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "sort"
+ "testing"
+ "unicode"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestAmbiguousCharacters(t *testing.T) {
+ for locale, ambiguous := range AmbiguousCharacters {
+ assert.Equal(t, locale, ambiguous.Locale)
+ assert.Equal(t, len(ambiguous.Confusable), len(ambiguous.With))
+ assert.True(t, sort.SliceIsSorted(ambiguous.Confusable, func(i, j int) bool {
+ return ambiguous.Confusable[i] < ambiguous.Confusable[j]
+ }))
+
+ for _, confusable := range ambiguous.Confusable {
+ assert.True(t, unicode.Is(ambiguous.RangeTable, confusable))
+ i := sort.Search(len(ambiguous.Confusable), func(j int) bool {
+ return ambiguous.Confusable[j] >= confusable
+ })
+ found := i < len(ambiguous.Confusable) && ambiguous.Confusable[i] == confusable
+ assert.True(t, found, "%c is not in %d", confusable, i)
+ }
+ }
+}
diff --git a/modules/charset/breakwriter.go b/modules/charset/breakwriter.go
new file mode 100644
index 000000000000..619826ff21b1
--- /dev/null
+++ b/modules/charset/breakwriter.go
@@ -0,0 +1,44 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "bytes"
+ "io"
+)
+
+// BreakWriter wraps an io.Writer to always write '\n' as '
'
+type BreakWriter struct {
+ io.Writer
+}
+
+// Write writes the provided byte slice transparently replacing '\n' with '
'
+func (b *BreakWriter) Write(bs []byte) (n int, err error) {
+ pos := 0
+ for pos < len(bs) {
+ idx := bytes.IndexByte(bs[pos:], '\n')
+ if idx < 0 {
+ wn, err := b.Writer.Write(bs[pos:])
+ return n + wn, err
+ }
+
+ if idx > 0 {
+ wn, err := b.Writer.Write(bs[pos : pos+idx])
+ n += wn
+ if err != nil {
+ return n, err
+ }
+ }
+
+ if _, err = b.Writer.Write([]byte("
")); err != nil {
+ return n, err
+ }
+ pos += idx + 1
+
+ n++
+ }
+
+ return n, err
+}
diff --git a/modules/charset/breakwriter_test.go b/modules/charset/breakwriter_test.go
new file mode 100644
index 000000000000..6bbed42ea54c
--- /dev/null
+++ b/modules/charset/breakwriter_test.go
@@ -0,0 +1,69 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "strings"
+ "testing"
+)
+
+func TestBreakWriter_Write(t *testing.T) {
+ tests := []struct {
+ name string
+ kase string
+ expect string
+ wantErr bool
+ }{
+ {
+ name: "noline",
+ kase: "abcdefghijklmnopqrstuvwxyz",
+ expect: "abcdefghijklmnopqrstuvwxyz",
+ },
+ {
+ name: "endline",
+ kase: "abcdefghijklmnopqrstuvwxyz\n",
+ expect: "abcdefghijklmnopqrstuvwxyz
",
+ },
+ {
+ name: "startline",
+ kase: "\nabcdefghijklmnopqrstuvwxyz",
+ expect: "
abcdefghijklmnopqrstuvwxyz",
+ },
+ {
+ name: "onlyline",
+ kase: "\n\n\n",
+ expect: "
",
+ },
+ {
+ name: "empty",
+ kase: "",
+ expect: "",
+ },
+ {
+ name: "midline",
+ kase: "\nabc\ndefghijkl\nmnopqrstuvwxy\nz",
+ expect: "
abc
defghijkl
mnopqrstuvwxy
z",
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.name, func(t *testing.T) {
+ buf := &strings.Builder{}
+ b := &BreakWriter{
+ Writer: buf,
+ }
+ n, err := b.Write([]byte(tt.kase))
+ if (err != nil) != tt.wantErr {
+ t.Errorf("BreakWriter.Write() error = %v, wantErr %v", err, tt.wantErr)
+ return
+ }
+ if n != len(tt.kase) {
+ t.Errorf("BreakWriter.Write() = %v, want %v", n, len(tt.kase))
+ }
+ if buf.String() != tt.expect {
+ t.Errorf("BreakWriter.Write() wrote %q, want %v", buf.String(), tt.expect)
+ }
+ })
+ }
+}
diff --git a/modules/charset/escape.go b/modules/charset/escape.go
index 9c1baafba326..b264a569ff5e 100644
--- a/modules/charset/escape.go
+++ b/modules/charset/escape.go
@@ -1,236 +1,58 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
+// Copyright 2022 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
+//go:generate go run invisible/generate.go -v -o ./invisible_gen.go
+
+//go:generate go run ambiguous/generate.go -v -o ./ambiguous_gen.go ambiguous/ambiguous.json
+
package charset
import (
- "bytes"
- "fmt"
"io"
"strings"
- "unicode"
- "unicode/utf8"
- "golang.org/x/text/unicode/bidi"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/translation"
)
-// EscapeStatus represents the findings of the unicode escaper
-type EscapeStatus struct {
- Escaped bool
- HasError bool
- HasBadRunes bool
- HasControls bool
- HasSpaces bool
- HasMarks bool
- HasBIDI bool
- BadBIDI bool
- HasRTLScript bool
- HasLTRScript bool
-}
-
-// Or combines two EscapeStatus structs into one representing the conjunction of the two
-func (status EscapeStatus) Or(other EscapeStatus) EscapeStatus {
- st := status
- st.Escaped = st.Escaped || other.Escaped
- st.HasError = st.HasError || other.HasError
- st.HasBadRunes = st.HasBadRunes || other.HasBadRunes
- st.HasControls = st.HasControls || other.HasControls
- st.HasSpaces = st.HasSpaces || other.HasSpaces
- st.HasMarks = st.HasMarks || other.HasMarks
- st.HasBIDI = st.HasBIDI || other.HasBIDI
- st.BadBIDI = st.BadBIDI || other.BadBIDI
- st.HasRTLScript = st.HasRTLScript || other.HasRTLScript
- st.HasLTRScript = st.HasLTRScript || other.HasLTRScript
- return st
-}
+// RuneNBSP is the codepoint for NBSP
+const RuneNBSP = 0xa0
-// EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string
-func EscapeControlString(text string) (EscapeStatus, string) {
+// EscapeControlHTML escapes the unicode control sequences in a provided html document
+func EscapeControlHTML(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) {
sb := &strings.Builder{}
- escaped, _ := EscapeControlReader(strings.NewReader(text), sb)
- return escaped, sb.String()
-}
+ outputStream := &HTMLStreamerWriter{Writer: sb}
+ streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
-// EscapeControlBytes escapes the unicode control sequences a provided []byte and returns the findings as an EscapeStatus and the escaped []byte
-func EscapeControlBytes(text []byte) (EscapeStatus, []byte) {
- buf := &bytes.Buffer{}
- escaped, _ := EscapeControlReader(bytes.NewReader(text), buf)
- return escaped, buf.Bytes()
+ if err := StreamHTML(strings.NewReader(text), streamer); err != nil {
+ streamer.escaped.HasError = true
+ log.Error("Error whilst escaping: %v", err)
+ }
+ return streamer.escaped, sb.String()
}
-// EscapeControlReader escapes the unicode control sequences a provided Reader writing the escaped output to the output and returns the findings as an EscapeStatus and an error
-func EscapeControlReader(text io.Reader, output io.Writer) (escaped EscapeStatus, err error) {
- buf := make([]byte, 4096)
- readStart := 0
- runeCount := 0
- var n int
- var writePos int
-
- lineHasBIDI := false
- lineHasRTLScript := false
- lineHasLTRScript := false
-
-readingloop:
- for err == nil {
- n, err = text.Read(buf[readStart:])
- bs := buf[:n+readStart]
- n = len(bs)
- i := 0
+// EscapeControlReaders escapes the unicode control sequences in a provider reader and writer in a locale and returns the findings as an EscapeStatus and the escaped []byte
+func EscapeControlReader(reader io.Reader, writer io.Writer, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, err error) {
+ outputStream := &HTMLStreamerWriter{Writer: writer}
+ streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
- for i < len(bs) {
- r, size := utf8.DecodeRune(bs[i:])
- runeCount++
-
- // Now handle the codepoints
- switch {
- case r == utf8.RuneError:
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- writePos = i
- }
- // runes can be at most 4 bytes - so...
- if len(bs)-i <= 3 {
- // if not request more data
- copy(buf, bs[i:])
- readStart = n - i
- writePos = 0
- continue readingloop
- }
- // this is a real broken rune
- escaped.HasBadRunes = true
- escaped.Escaped = true
- if err = writeBroken(output, bs[i:i+size]); err != nil {
- escaped.HasError = true
- return
- }
- writePos += size
- case r == '\n':
- if lineHasBIDI && !lineHasRTLScript && lineHasLTRScript {
- escaped.BadBIDI = true
- }
- lineHasBIDI = false
- lineHasRTLScript = false
- lineHasLTRScript = false
-
- case runeCount == 1 && r == 0xFEFF: // UTF BOM
- // the first BOM is safe
- case r == '\r' || r == '\t' || r == ' ':
- // These are acceptable control characters and space characters
- case unicode.IsSpace(r):
- escaped.HasSpaces = true
- escaped.Escaped = true
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- }
- if err = writeEscaped(output, r); err != nil {
- escaped.HasError = true
- return
- }
- writePos = i + size
- case unicode.Is(unicode.Bidi_Control, r):
- escaped.Escaped = true
- escaped.HasBIDI = true
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- }
- lineHasBIDI = true
- if err = writeEscaped(output, r); err != nil {
- escaped.HasError = true
- return
- }
- writePos = i + size
- case unicode.Is(unicode.C, r):
- escaped.Escaped = true
- escaped.HasControls = true
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- }
- if err = writeEscaped(output, r); err != nil {
- escaped.HasError = true
- return
- }
- writePos = i + size
- case unicode.Is(unicode.M, r):
- escaped.Escaped = true
- escaped.HasMarks = true
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- }
- if err = writeEscaped(output, r); err != nil {
- escaped.HasError = true
- return
- }
- writePos = i + size
- default:
- p, _ := bidi.Lookup(bs[i : i+size])
- c := p.Class()
- if c == bidi.R || c == bidi.AL {
- lineHasRTLScript = true
- escaped.HasRTLScript = true
- } else if c == bidi.L {
- lineHasLTRScript = true
- escaped.HasLTRScript = true
- }
- }
- i += size
- }
- if n > 0 {
- // we read something...
- // write everything unwritten
- if writePos < i {
- if _, err = output.Write(bs[writePos:i]); err != nil {
- escaped.HasError = true
- return
- }
- }
-
- // reset the starting positions for the next read
- readStart = 0
- writePos = 0
- }
- }
- if readStart > 0 {
- // this means that there is an incomplete or broken rune at 0-readStart and we read nothing on the last go round
- escaped.Escaped = true
- escaped.HasBadRunes = true
- if err = writeBroken(output, buf[:readStart]); err != nil {
- escaped.HasError = true
- return
- }
- }
- if err == io.EOF {
- if lineHasBIDI && !lineHasRTLScript && lineHasLTRScript {
- escaped.BadBIDI = true
- }
- err = nil
- return
+ if err = StreamHTML(reader, streamer); err != nil {
+ streamer.escaped.HasError = true
+ log.Error("Error whilst escaping: %v", err)
}
- escaped.HasError = true
- return escaped, err
+ return streamer.escaped, err
}
-func writeBroken(output io.Writer, bs []byte) (err error) {
- _, err = fmt.Fprintf(output, `
<%X> `, bs)
- return err
-}
+// EscapeControlString escapes the unicode control sequences in a provided string and returns the findings as an EscapeStatus and the escaped string
+func EscapeControlString(text string, locale translation.Locale, allowed ...rune) (escaped *EscapeStatus, output string) {
+ sb := &strings.Builder{}
+ outputStream := &HTMLStreamerWriter{Writer: sb}
+ streamer := NewEscapeStreamer(locale, outputStream, allowed...).(*escapeStreamer)
-func writeEscaped(output io.Writer, r rune) (err error) {
- _, err = fmt.Fprintf(output, `
%c `, r, r)
- return err
+ if err := streamer.Text(text); err != nil {
+ streamer.escaped.HasError = true
+ log.Error("Error whilst escaping: %v", err)
+ }
+ return streamer.escaped, sb.String()
}
diff --git a/modules/charset/escape_status.go b/modules/charset/escape_status.go
new file mode 100644
index 000000000000..7ff0ef112bb2
--- /dev/null
+++ b/modules/charset/escape_status.go
@@ -0,0 +1,28 @@
+// Copyright 2021 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+// EscapeStatus represents the findings of the unicode escaper
+type EscapeStatus struct {
+ Escaped bool
+ HasError bool
+ HasBadRunes bool
+ HasInvisible bool
+ HasAmbiguous bool
+}
+
+// Or combines two EscapeStatus structs into one representing the conjunction of the two
+func (status *EscapeStatus) Or(other *EscapeStatus) *EscapeStatus {
+ st := status
+ if status == nil {
+ st = &EscapeStatus{}
+ }
+ st.Escaped = st.Escaped || other.Escaped
+ st.HasError = st.HasError || other.HasError
+ st.HasBadRunes = st.HasBadRunes || other.HasBadRunes
+ st.HasAmbiguous = st.HasAmbiguous || other.HasAmbiguous
+ st.HasInvisible = st.HasInvisible || other.HasInvisible
+ return st
+}
diff --git a/modules/charset/escape_stream.go b/modules/charset/escape_stream.go
new file mode 100644
index 000000000000..8c17136c9dc6
--- /dev/null
+++ b/modules/charset/escape_stream.go
@@ -0,0 +1,297 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "fmt"
+ "regexp"
+ "sort"
+ "strings"
+ "unicode"
+ "unicode/utf8"
+
+ "code.gitea.io/gitea/modules/translation"
+
+ "golang.org/x/net/html"
+)
+
+// VScode defaultWordRegexp
+var defaultWordRegexp = regexp.MustCompile(`(-?\d*\.\d\w*)|([^\` + "`" + `\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s\x00-\x1f]+)`)
+
+func NewEscapeStreamer(locale translation.Locale, next HTMLStreamer, allowed ...rune) HTMLStreamer {
+ return &escapeStreamer{
+ escaped: &EscapeStatus{},
+ PassthroughHTMLStreamer: *NewPassthroughStreamer(next),
+ locale: locale,
+ ambiguousTables: AmbiguousTablesForLocale(locale),
+ allowed: allowed,
+ }
+}
+
+type escapeStreamer struct {
+ PassthroughHTMLStreamer
+ escaped *EscapeStatus
+ locale translation.Locale
+ ambiguousTables []*AmbiguousTable
+ allowed []rune
+}
+
+func (e *escapeStreamer) EscapeStatus() *EscapeStatus {
+ return e.escaped
+}
+
+// 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
+ if len(data) > len(UTF8BOM) && data[:len(UTF8BOM)] == string(UTF8BOM) {
+ _, _ = sb.WriteString(data[:len(UTF8BOM)])
+ pos = len(UTF8BOM)
+ }
+ for pos < len(data) {
+ nextIdxs := defaultWordRegexp.FindStringIndex(data[pos:])
+ if nextIdxs == nil {
+ until = len(data)
+ next = until
+ } else {
+ until, next = nextIdxs[0]+pos, nextIdxs[1]+pos
+ }
+
+ // from pos until until we know that the runes are not \r\t\n or even ' '
+ runes := make([]rune, 0, next-until)
+ positions := make([]int, 0, next-until+1)
+
+ for pos < until {
+ r, sz := utf8.DecodeRune([]byte(data)[pos:])
+ positions = positions[:0]
+ positions = append(positions, pos, pos+sz)
+ types, confusables, _ := e.runeTypes(r)
+ if err := e.handleRunes(data, []rune{r}, positions, types, confusables, sb); err != nil {
+ return err
+ }
+ pos += sz
+ }
+
+ for i := pos; i < next; {
+ r, sz := utf8.DecodeRune([]byte(data)[i:])
+ runes = append(runes, r)
+ positions = append(positions, i)
+ i += sz
+ }
+ positions = append(positions, next)
+ types, confusables, runeCounts := e.runeTypes(runes...)
+ if runeCounts.needsEscape() {
+ if err := e.handleRunes(data, runes, positions, types, confusables, sb); err != nil {
+ return err
+ }
+ } else {
+ _, _ = sb.Write([]byte(data)[pos:next])
+ }
+ pos = next
+ }
+ if sb.Len() > 0 {
+ if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+func (e *escapeStreamer) handleRunes(data string, runes []rune, positions []int, types []runeType, confusables []rune, sb *strings.Builder) error {
+ for i, r := range runes {
+ switch types[i] {
+ case brokenRuneType:
+ if sb.Len() > 0 {
+ if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil {
+ return err
+ }
+ sb.Reset()
+ }
+ end := positions[i+1]
+ start := positions[i]
+ if err := e.brokenRune([]byte(data)[start:end]); err != nil {
+ return err
+ }
+ case ambiguousRuneType:
+ if sb.Len() > 0 {
+ if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil {
+ return err
+ }
+ sb.Reset()
+ }
+ if err := e.ambiguousRune(r, confusables[0]); err != nil {
+ return err
+ }
+ confusables = confusables[1:]
+ case invisibleRuneType:
+ if sb.Len() > 0 {
+ if err := e.PassthroughHTMLStreamer.Text(sb.String()); err != nil {
+ return err
+ }
+ sb.Reset()
+ }
+ if err := e.invisibleRune(r); err != nil {
+ return err
+ }
+ default:
+ _, _ = sb.WriteRune(r)
+ }
+ }
+ return nil
+}
+
+func (e *escapeStreamer) brokenRune(bs []byte) error {
+ e.escaped.Escaped = true
+ e.escaped.HasBadRunes = true
+
+ if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
+ Key: "class",
+ Val: "broken-code-point",
+ }); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.Text(fmt.Sprintf("<%X>", bs)); err != nil {
+ return err
+ }
+
+ return e.PassthroughHTMLStreamer.EndTag("span")
+}
+
+func (e *escapeStreamer) ambiguousRune(r, c rune) error {
+ e.escaped.Escaped = true
+ e.escaped.HasAmbiguous = true
+
+ if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
+ Key: "class",
+ Val: "ambiguous-code-point tooltip",
+ }, html.Attribute{
+ Key: "data-content",
+ Val: e.locale.Tr("repo.ambiguous_character", r, c),
+ }); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
+ Key: "class",
+ Val: "char",
+ }); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.Text(string(r)); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.EndTag("span"); err != nil {
+ return err
+ }
+
+ return e.PassthroughHTMLStreamer.EndTag("span")
+}
+
+func (e *escapeStreamer) invisibleRune(r rune) error {
+ e.escaped.Escaped = true
+ e.escaped.HasInvisible = true
+
+ if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
+ Key: "class",
+ Val: "escaped-code-point",
+ }, html.Attribute{
+ Key: "data-escaped",
+ Val: fmt.Sprintf("[U+%04X]", r),
+ }); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.StartTag("span", html.Attribute{
+ Key: "class",
+ Val: "char",
+ }); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.Text(string(r)); err != nil {
+ return err
+ }
+ if err := e.PassthroughHTMLStreamer.EndTag("span"); err != nil {
+ return err
+ }
+
+ return e.PassthroughHTMLStreamer.EndTag("span")
+}
+
+type runeCountType struct {
+ numBasicRunes int
+ numNonConfusingNonBasicRunes int
+ numAmbiguousRunes int
+ numInvisibleRunes int
+ numBrokenRunes int
+}
+
+func (counts runeCountType) needsEscape() bool {
+ if counts.numBrokenRunes > 0 {
+ return true
+ }
+ if counts.numBasicRunes == 0 &&
+ counts.numNonConfusingNonBasicRunes > 0 {
+ return false
+ }
+ return counts.numAmbiguousRunes > 0 || counts.numInvisibleRunes > 0
+}
+
+type runeType int
+
+const (
+ basicASCIIRuneType runeType = iota //nolint // <- This is technically deadcode but its self-documenting so it should stay
+ brokenRuneType
+ nonBasicASCIIRuneType
+ ambiguousRuneType
+ invisibleRuneType
+)
+
+func (e *escapeStreamer) runeTypes(runes ...rune) (types []runeType, confusables []rune, runeCounts runeCountType) {
+ types = make([]runeType, len(runes))
+ for i, r := range runes {
+ var confusable rune
+ switch {
+ case r == utf8.RuneError:
+ types[i] = brokenRuneType
+ runeCounts.numBrokenRunes++
+ case r == ' ' || r == '\t' || r == '\n':
+ runeCounts.numBasicRunes++
+ case e.isAllowed(r):
+ if r > 0x7e || r < 0x20 {
+ types[i] = nonBasicASCIIRuneType
+ runeCounts.numNonConfusingNonBasicRunes++
+ } else {
+ runeCounts.numBasicRunes++
+ }
+ case unicode.Is(InvisibleRanges, r):
+ types[i] = invisibleRuneType
+ runeCounts.numInvisibleRunes++
+ case unicode.IsControl(r):
+ types[i] = invisibleRuneType
+ runeCounts.numInvisibleRunes++
+ case isAmbiguous(r, &confusable, e.ambiguousTables...):
+ confusables = append(confusables, confusable)
+ types[i] = ambiguousRuneType
+ runeCounts.numAmbiguousRunes++
+ case r > 0x7e || r < 0x20:
+ types[i] = nonBasicASCIIRuneType
+ runeCounts.numNonConfusingNonBasicRunes++
+ default:
+ runeCounts.numBasicRunes++
+ }
+ }
+ return types, confusables, runeCounts
+}
+
+func (e *escapeStreamer) isAllowed(r rune) bool {
+ if len(e.allowed) == 0 {
+ return false
+ }
+ if len(e.allowed) == 1 {
+ return e.allowed[0] == r
+ }
+
+ return sort.Search(len(e.allowed), func(i int) bool {
+ return e.allowed[i] >= r
+ }) >= 0
+}
diff --git a/modules/charset/escape_test.go b/modules/charset/escape_test.go
index 01ccca77249b..8063e115424c 100644
--- a/modules/charset/escape_test.go
+++ b/modules/charset/escape_test.go
@@ -8,6 +8,8 @@ import (
"reflect"
"strings"
"testing"
+
+ "code.gitea.io/gitea/modules/translation"
)
type escapeControlTest struct {
@@ -25,37 +27,37 @@ var escapeControlTests = []escapeControlTest{
name: "single line western",
text: "single line western",
result: "single line western",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "multi line western",
text: "single line western\nmulti line western\n",
result: "single line western\nmulti line western\n",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "multi line western non-breaking space",
text: "single line western\nmulti line western\n",
result: `single line
western` + "\n" + `multi line
western` + "\n",
- status: EscapeStatus{Escaped: true, HasLTRScript: true, HasSpaces: true},
+ status: EscapeStatus{Escaped: true, HasInvisible: true},
},
{
name: "mixed scripts: western + japanese",
text: "日属秘ぞしちゅ。Then some western.",
result: "日属秘ぞしちゅ。Then some western.",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "japanese",
text: "日属秘ぞしちゅ。",
result: "日属秘ぞしちゅ。",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "hebrew",
text: "עד תקופת יוון העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה",
- result: "עד תקופת יוון העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה",
- status: EscapeStatus{HasRTLScript: true},
+ result: `עד תקופת
י ו ו ן העתיקה היה העיסוק במתמטיקה תכליתי בלבד: היא שימשה כאוסף של נוסחאות לחישוב קרקע, אוכלוסין וכו'. פריצת הדרך של היוונים, פרט לתרומותיהם הגדולות לידע המתמטי, הייתה בלימוד המתמטיקה כשלעצמה, מתוקף ערכה הרוחני. יחסם של חלק מהיוונים הקדמונים למתמטיקה היה דתי - למשל, הכת שאסף סביבו פיתגורס האמינה כי המתמטיקה היא הבסיס לכל הדברים. היוונים נחשבים ליוצרי מושג ההוכחה המתמטית, וכן לראשונים שעסקו במתמטיקה לשם עצמה, כלומר כתחום מחקרי עיוני ומופשט ולא רק כעזר שימושי. עם זאת, לצדה`,
+ status: EscapeStatus{Escaped: true, HasAmbiguous: true},
},
{
name: "more hebrew",
@@ -64,12 +66,12 @@ var escapeControlTests = []escapeControlTest{
המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"ס - 546 לפנה"ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף.
בשנים 582 לפנה"ס עד 496 לפנה"ס, בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`,
- result: `בתקופה מאוחרת יותר, השתמשו היוונים בשיטת סימון מתקדמת יותר, שבה הוצגו המספרים לפי 22 אותיות האלפבית היווני. לסימון המספרים בין 1 ל-9 נקבעו תשע האותיות הראשונות, בתוספת גרש ( ' ) בצד ימין של האות, למעלה; תשע האותיות הבאות ייצגו את העשרות מ-10 עד 90, והבאות את המאות. לסימון הספרות בין 1000 ל-900,000, השתמשו היוונים באותן אותיות, אך הוסיפו לאותיות את הגרש דווקא מצד שמאל של האותיות, למטה. ממיליון ומעלה, כנראה השתמשו היוונים בשני תגים במקום אחד.
+ result: `בתקופה מאוחרת יותר, השתמשו היוונים בשיטת סימון מתקדמת יותר, שבה הוצגו המספרים לפי 22 אותיות האלפבית היווני. לסימון המספרים בין 1 ל-9 נקבעו תשע האותיות הראשונות, בתוספת גרש ( ' ) בצד ימין של האות, למעלה; תשע האותיות הבאות ייצגו את העשרות מ-10 עד 90, והבאות את המאות. לסימון הספרות בין 1000 ל-900,000, השתמשו היוונים באותן אותיות, אך הוסיפו לאותיות את הגרש דווקא מצד שמאל של האותיות, למטה. ממיליון ומעלה, כנראה השתמשו היוונים בשני תגים במקום אחד.
- המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"ס - 546 לפנה"ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף.
+ המתמטיקאי הבולט הראשון ביוון העתיקה, ויש האומרים בתולדות האנושות, הוא תאלס (624 לפנה"
ס - 546 לפנה"
ס בקירוב).[1] לא יהיה זה משולל יסוד להניח שהוא האדם הראשון שהוכיח משפט מתמטי, ולא רק גילה אותו. תאלס הוכיח שישרים מקבילים חותכים מצד אחד של שוקי זווית קטעים בעלי יחסים שווים (משפט תאלס הראשון), שהזווית המונחת על קוטר במעגל היא זווית ישרה (משפט תאלס השני), שהקוטר מחלק את המעגל לשני חלקים שווים, ושזוויות הבסיס במשולש שווה-שוקיים שוות זו לזו. מיוחסות לו גם שיטות למדידת גובהן של הפירמידות בעזרת מדידת צילן ולקביעת מיקומה של ספינה הנראית מן החוף.
- בשנים 582 לפנה"ס עד 496 לפנה"ס, בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`,
- status: EscapeStatus{HasRTLScript: true},
+ בשנים 582 לפנה"
ס עד 496 לפנה"
ס , בקירוב, חי מתמטיקאי חשוב במיוחד - פיתגורס. המקורות הראשוניים עליו מועטים, וההיסטוריונים מתקשים להפריד את העובדות משכבת המסתורין והאגדות שנקשרו בו. ידוע שסביבו התקבצה האסכולה הפיתגוראית מעין כת פסבדו-מתמטית שהאמינה ש"הכל מספר", או ליתר דיוק הכל ניתן לכימות, וייחסה למספרים משמעויות מיסטיות. ככל הנראה הפיתגוראים ידעו לבנות את הגופים האפלטוניים, הכירו את הממוצע האריתמטי, הממוצע הגאומטרי והממוצע ההרמוני והגיעו להישגים חשובים נוספים. ניתן לומר שהפיתגוראים גילו את היותו של השורש הריבועי של 2, שהוא גם האלכסון בריבוע שאורך צלעותיו 1, אי רציונלי, אך תגליתם הייתה למעשה רק שהקטעים "חסרי מידה משותפת", ומושג המספר האי רציונלי מאוחר יותר.[2] אזכור ראשון לקיומם של קטעים חסרי מידה משותפת מופיע בדיאלוג "תאיטיטוס" של אפלטון, אך רעיון זה היה מוכר עוד קודם לכן, במאה החמישית לפנה"
ס להיפאסוס, בן האסכולה הפיתגוראית, ואולי לפיתגורס עצמו.[3]`,
+ status: EscapeStatus{Escaped: true, HasAmbiguous: true},
},
{
name: "Mixed RTL+LTR",
@@ -79,10 +81,7 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`,
result: `Many computer programs fail to display bidirectional text correctly.
For example, the Hebrew name Sarah (שרה) is spelled: sin (ש) (which appears rightmost),
then resh (ר), and finally heh (ה) (which should appear leftmost).`,
- status: EscapeStatus{
- HasRTLScript: true,
- HasLTRScript: true,
- },
+ status: EscapeStatus{},
},
{
name: "Mixed RTL+LTR+BIDI",
@@ -90,32 +89,27 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`,
For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" +
`sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).`,
result: `Many computer programs fail to display bidirectional text correctly.
- For example, the Hebrew name Sarah
` + "\u2067" + ` שרה
` + "\u2066" + ` ` + "\n" +
+ For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" +
`sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).`,
- status: EscapeStatus{
- Escaped: true,
- HasBIDI: true,
- HasRTLScript: true,
- HasLTRScript: true,
- },
+ status: EscapeStatus{},
},
{
name: "Accented characters",
text: string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}),
result: string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba}),
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "Program",
text: "string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba})",
result: "string([]byte{0xc3, 0xa1, 0xc3, 0xa9, 0xc3, 0xad, 0xc3, 0xb3, 0xc3, 0xba})",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
{
name: "CVE testcase",
text: "if access_level != \"user\u202E \u2066// Check if admin\u2069 \u2066\" {",
- result: `if access_level != "user
` + "\u202e" + ` ` + "\u2066" + ` // Check if admin
` + "\u2069" + ` ` + "\u2066" + ` " {`,
- status: EscapeStatus{Escaped: true, HasBIDI: true, BadBIDI: true, HasLTRScript: true},
+ result: `if access_level != "user
` + "\u202e" + ` ` + "\u2066" + ` // Check if admin
` + "\u2069" + ` ` + "\u2066" + ` " {`,
+ status: EscapeStatus{Escaped: true, HasInvisible: true},
},
{
name: "Mixed testcase with fail",
@@ -124,10 +118,10 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`,
`sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).` +
"\nif access_level != \"user\u202E \u2066// Check if admin\u2069 \u2066\" {\n",
result: `Many computer programs fail to display bidirectional text correctly.
- For example, the Hebrew name Sarah
` + "\u2067" + ` שרה
` + "\u2066" + ` ` + "\n" +
+ For example, the Hebrew name Sarah ` + "\u2067" + `שרה` + "\u2066\n" +
`sin (ש) (which appears rightmost), then resh (ר), and finally heh (ה) (which should appear leftmost).` +
- "\n" + `if access_level != "user
` + "\u202e" + ` ` + "\u2066" + ` // Check if admin
` + "\u2069" + ` ` + "\u2066" + ` " {` + "\n",
- status: EscapeStatus{Escaped: true, HasBIDI: true, BadBIDI: true, HasLTRScript: true, HasRTLScript: true},
+ "\n" + `if access_level != "user
` + "\u202e" + ` ` + "\u2066" + ` // Check if admin
` + "\u2069" + ` ` + "\u2066" + ` " {` + "\n",
+ status: EscapeStatus{Escaped: true, HasInvisible: true},
},
{
// UTF-8/16/32 all use the same codepoint for BOM
@@ -135,15 +129,16 @@ then resh (ר), and finally heh (ה) (which should appear leftmost).`,
name: "UTF BOM",
text: "\xef\xbb\xbftest",
result: "\xef\xbb\xbftest",
- status: EscapeStatus{HasLTRScript: true},
+ status: EscapeStatus{},
},
}
func TestEscapeControlString(t *testing.T) {
for _, tt := range escapeControlTests {
t.Run(tt.name, func(t *testing.T) {
- status, result := EscapeControlString(tt.text)
- if !reflect.DeepEqual(status, tt.status) {
+ locale := translation.NewLocale("en_US")
+ status, result := EscapeControlString(tt.text, locale)
+ if !reflect.DeepEqual(*status, tt.status) {
t.Errorf("EscapeControlString() status = %v, wanted= %v", status, tt.status)
}
if result != tt.result {
@@ -153,20 +148,6 @@ func TestEscapeControlString(t *testing.T) {
}
}
-func TestEscapeControlBytes(t *testing.T) {
- for _, tt := range escapeControlTests {
- t.Run(tt.name, func(t *testing.T) {
- status, result := EscapeControlBytes([]byte(tt.text))
- if !reflect.DeepEqual(status, tt.status) {
- t.Errorf("EscapeControlBytes() status = %v, wanted= %v", status, tt.status)
- }
- if string(result) != tt.result {
- t.Errorf("EscapeControlBytes()\nresult= %v,\nwanted= %v", result, tt.result)
- }
- })
- }
-}
-
func TestEscapeControlReader(t *testing.T) {
// lets add some control characters to the tests
tests := make([]escapeControlTest, 0, len(escapeControlTests)*3)
@@ -184,16 +165,7 @@ func TestEscapeControlReader(t *testing.T) {
test.text = addPrefix("\u001E", test.text)
test.result = addPrefix(`
`+"\u001e"+` `, test.result)
test.status.Escaped = true
- test.status.HasControls = true
- tests = append(tests, test)
- }
-
- for _, test := range escapeControlTests {
- test.name += " (+Mark)"
- test.text = addPrefix("\u0300", test.text)
- test.result = addPrefix(`
`+"\u0300"+` `, test.result)
- test.status.Escaped = true
- test.status.HasMarks = true
+ test.status.HasInvisible = true
tests = append(tests, test)
}
@@ -201,13 +173,13 @@ func TestEscapeControlReader(t *testing.T) {
t.Run(tt.name, func(t *testing.T) {
input := strings.NewReader(tt.text)
output := &strings.Builder{}
- status, err := EscapeControlReader(input, output)
+ status, err := EscapeControlReader(input, output, translation.NewLocale("en_US"))
result := output.String()
if err != nil {
t.Errorf("EscapeControlReader(): err = %v", err)
}
- if !reflect.DeepEqual(status, tt.status) {
+ if !reflect.DeepEqual(*status, tt.status) {
t.Errorf("EscapeControlReader() status = %v, wanted= %v", status, tt.status)
}
if result != tt.result {
@@ -223,5 +195,5 @@ func TestEscapeControlReader_panic(t *testing.T) {
for i := 0; i < 6826; i++ {
bs = append(bs, []byte("—")...)
}
- _, _ = EscapeControlBytes(bs)
+ _, _ = EscapeControlString(string(bs), translation.NewLocale("en_US"))
}
diff --git a/modules/charset/htmlstream.go b/modules/charset/htmlstream.go
new file mode 100644
index 000000000000..b354ce6a48a1
--- /dev/null
+++ b/modules/charset/htmlstream.go
@@ -0,0 +1,201 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import (
+ "fmt"
+ "io"
+
+ "golang.org/x/net/html"
+)
+
+// HTMLStreamer represents a SAX-like interface for HTML
+type HTMLStreamer interface {
+ Error(err error) error
+ Doctype(data string) error
+ Comment(data string) error
+ StartTag(data string, attrs ...html.Attribute) error
+ SelfClosingTag(data string, attrs ...html.Attribute) error
+ EndTag(data string) error
+ Text(data string) error
+}
+
+// PassthroughHTMLStreamer is a passthrough streamer
+type PassthroughHTMLStreamer struct {
+ next HTMLStreamer
+}
+
+func NewPassthroughStreamer(next HTMLStreamer) *PassthroughHTMLStreamer {
+ return &PassthroughHTMLStreamer{next: next}
+}
+
+var _ (HTMLStreamer) = &PassthroughHTMLStreamer{}
+
+// Error tells the next streamer in line that there is an error
+func (p *PassthroughHTMLStreamer) Error(err error) error {
+ return p.next.Error(err)
+}
+
+// Doctype tells the next streamer what the doctype is
+func (p *PassthroughHTMLStreamer) Doctype(data string) error {
+ return p.next.Doctype(data)
+}
+
+// Comment tells the next streamer there is a comment
+func (p *PassthroughHTMLStreamer) Comment(data string) error {
+ return p.next.Comment(data)
+}
+
+// StartTag tells the next streamer there is a starting tag
+func (p *PassthroughHTMLStreamer) StartTag(data string, attrs ...html.Attribute) error {
+ return p.next.StartTag(data, attrs...)
+}
+
+// SelfClosingTag tells the next streamer there is a self-closing tag
+func (p *PassthroughHTMLStreamer) SelfClosingTag(data string, attrs ...html.Attribute) error {
+ return p.next.SelfClosingTag(data, attrs...)
+}
+
+// EndTag tells the next streamer there is a end tag
+func (p *PassthroughHTMLStreamer) EndTag(data string) error {
+ return p.next.EndTag(data)
+}
+
+// Text tells the next streamer there is a text
+func (p *PassthroughHTMLStreamer) Text(data string) error {
+ return p.next.Text(data)
+}
+
+// HTMLStreamWriter acts as a writing sink
+type HTMLStreamerWriter struct {
+ io.Writer
+ err error
+}
+
+// Write implements io.Writer
+func (h *HTMLStreamerWriter) Write(data []byte) (int, error) {
+ if h.err != nil {
+ return 0, h.err
+ }
+ return h.Writer.Write(data)
+}
+
+// Write implements io.StringWriter
+func (h *HTMLStreamerWriter) WriteString(data string) (int, error) {
+ if h.err != nil {
+ return 0, h.err
+ }
+ return h.Writer.Write([]byte(data))
+}
+
+// Error tells the next streamer in line that there is an error
+func (h *HTMLStreamerWriter) Error(err error) error {
+ if h.err == nil {
+ h.err = err
+ }
+ return h.err
+}
+
+// Doctype tells the next streamer what the doctype is
+func (h *HTMLStreamerWriter) Doctype(data string) error {
+ _, h.err = h.WriteString("")
+ return h.err
+}
+
+// Comment tells the next streamer there is a comment
+func (h *HTMLStreamerWriter) Comment(data string) error {
+ _, h.err = h.WriteString("")
+ return h.err
+}
+
+// StartTag tells the next streamer there is a starting tag
+func (h *HTMLStreamerWriter) StartTag(data string, attrs ...html.Attribute) error {
+ return h.startTag(data, attrs, false)
+}
+
+// SelfClosingTag tells the next streamer there is a self-closing tag
+func (h *HTMLStreamerWriter) SelfClosingTag(data string, attrs ...html.Attribute) error {
+ return h.startTag(data, attrs, true)
+}
+
+func (h *HTMLStreamerWriter) startTag(data string, attrs []html.Attribute, selfclosing bool) error {
+ if _, h.err = h.WriteString("<" + data); h.err != nil {
+ return h.err
+ }
+ for _, attr := range attrs {
+ if _, h.err = h.WriteString(" " + attr.Key + "=\"" + html.EscapeString(attr.Val) + "\""); h.err != nil {
+ return h.err
+ }
+ }
+ if selfclosing {
+ if _, h.err = h.WriteString("/>"); h.err != nil {
+ return h.err
+ }
+ } else {
+ if _, h.err = h.WriteString(">"); h.err != nil {
+ return h.err
+ }
+ }
+ return h.err
+}
+
+// EndTag tells the next streamer there is a end tag
+func (h *HTMLStreamerWriter) EndTag(data string) error {
+ _, h.err = h.WriteString("" + data + ">")
+ return h.err
+}
+
+// Text tells the next streamer there is a text
+func (h *HTMLStreamerWriter) Text(data string) error {
+ _, h.err = h.WriteString(html.EscapeString(data))
+ return h.err
+}
+
+// StreamHTML streams an html to a provided streamer
+func StreamHTML(source io.Reader, streamer HTMLStreamer) error {
+ tokenizer := html.NewTokenizer(source)
+ for {
+ tt := tokenizer.Next()
+ switch tt {
+ case html.ErrorToken:
+ if tokenizer.Err() != io.EOF {
+ return tokenizer.Err()
+ }
+ return nil
+ case html.DoctypeToken:
+ token := tokenizer.Token()
+ if err := streamer.Doctype(token.Data); err != nil {
+ return err
+ }
+ case html.CommentToken:
+ token := tokenizer.Token()
+ if err := streamer.Comment(token.Data); err != nil {
+ return err
+ }
+ case html.StartTagToken:
+ token := tokenizer.Token()
+ if err := streamer.StartTag(token.Data, token.Attr...); err != nil {
+ return err
+ }
+ case html.SelfClosingTagToken:
+ token := tokenizer.Token()
+ if err := streamer.StartTag(token.Data, token.Attr...); err != nil {
+ return err
+ }
+ case html.EndTagToken:
+ token := tokenizer.Token()
+ if err := streamer.EndTag(token.Data); err != nil {
+ return err
+ }
+ case html.TextToken:
+ token := tokenizer.Token()
+ if err := streamer.Text(token.Data); err != nil {
+ return err
+ }
+ default:
+ return fmt.Errorf("unknown type of token: %d", tt)
+ }
+ }
+}
diff --git a/modules/charset/invisible/generate.go b/modules/charset/invisible/generate.go
new file mode 100644
index 000000000000..230ff0b83216
--- /dev/null
+++ b/modules/charset/invisible/generate.go
@@ -0,0 +1,111 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "bytes"
+ "flag"
+ "fmt"
+ "go/format"
+ "os"
+ "text/template"
+
+ "golang.org/x/text/unicode/rangetable"
+)
+
+// InvisibleRunes these are runes that vscode has assigned to be invisible
+// See https://github.com/hediet/vscode-unicode-data
+var InvisibleRunes = []rune{
+ 9, 10, 11, 12, 13, 32, 127, 160, 173, 847, 1564, 4447, 4448, 6068, 6069, 6155, 6156, 6157, 6158, 7355, 7356, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8203, 8204, 8205, 8206, 8207, 8234, 8235, 8236, 8237, 8238, 8239, 8287, 8288, 8289, 8290, 8291, 8292, 8293, 8294, 8295, 8296, 8297, 8298, 8299, 8300, 8301, 8302, 8303, 10240, 12288, 12644, 65024, 65025, 65026, 65027, 65028, 65029, 65030, 65031, 65032, 65033, 65034, 65035, 65036, 65037, 65038, 65039, 65279, 65440, 65520, 65521, 65522, 65523, 65524, 65525, 65526, 65527, 65528, 65532, 78844, 119155, 119156, 119157, 119158, 119159, 119160, 119161, 119162, 917504, 917505, 917506, 917507, 917508, 917509, 917510, 917511, 917512, 917513, 917514, 917515, 917516, 917517, 917518, 917519, 917520, 917521, 917522, 917523, 917524, 917525, 917526, 917527, 917528, 917529, 917530, 917531, 917532, 917533, 917534, 917535, 917536, 917537, 917538, 917539, 917540, 917541, 917542, 917543, 917544, 917545, 917546, 917547, 917548, 917549, 917550, 917551, 917552, 917553, 917554, 917555, 917556, 917557, 917558, 917559, 917560, 917561, 917562, 917563, 917564, 917565, 917566, 917567, 917568, 917569, 917570, 917571, 917572, 917573, 917574, 917575, 917576, 917577, 917578, 917579, 917580, 917581, 917582, 917583, 917584, 917585, 917586, 917587, 917588, 917589, 917590, 917591, 917592, 917593, 917594, 917595, 917596, 917597, 917598, 917599, 917600, 917601, 917602, 917603, 917604, 917605, 917606, 917607, 917608, 917609, 917610, 917611, 917612, 917613, 917614, 917615, 917616, 917617, 917618, 917619, 917620, 917621, 917622, 917623, 917624, 917625, 917626, 917627, 917628, 917629, 917630, 917631, 917760, 917761, 917762, 917763, 917764, 917765, 917766, 917767, 917768, 917769, 917770, 917771, 917772, 917773, 917774, 917775, 917776, 917777, 917778, 917779, 917780, 917781, 917782, 917783, 917784, 917785, 917786, 917787, 917788, 917789, 917790, 917791, 917792, 917793, 917794, 917795, 917796, 917797, 917798, 917799, 917800, 917801, 917802, 917803, 917804, 917805, 917806, 917807, 917808, 917809, 917810, 917811, 917812, 917813, 917814, 917815, 917816, 917817, 917818, 917819, 917820, 917821, 917822, 917823, 917824, 917825, 917826, 917827, 917828, 917829, 917830, 917831, 917832, 917833, 917834, 917835, 917836, 917837, 917838, 917839, 917840, 917841, 917842, 917843, 917844, 917845, 917846, 917847, 917848, 917849, 917850, 917851, 917852, 917853, 917854, 917855, 917856, 917857, 917858, 917859, 917860, 917861, 917862, 917863, 917864, 917865, 917866, 917867, 917868, 917869, 917870, 917871, 917872, 917873, 917874, 917875, 917876, 917877, 917878, 917879, 917880, 917881, 917882, 917883, 917884, 917885, 917886, 917887, 917888, 917889, 917890, 917891, 917892, 917893, 917894, 917895, 917896, 917897, 917898, 917899, 917900, 917901, 917902, 917903, 917904, 917905, 917906, 917907, 917908, 917909, 917910, 917911, 917912, 917913, 917914, 917915, 917916, 917917, 917918, 917919, 917920, 917921, 917922, 917923, 917924, 917925, 917926, 917927, 917928, 917929, 917930, 917931, 917932, 917933, 917934, 917935, 917936, 917937, 917938, 917939, 917940, 917941, 917942, 917943, 917944, 917945, 917946, 917947, 917948, 917949, 917950, 917951, 917952, 917953, 917954, 917955, 917956, 917957, 917958, 917959, 917960, 917961, 917962, 917963, 917964, 917965, 917966, 917967, 917968, 917969, 917970, 917971, 917972, 917973, 917974, 917975, 917976, 917977, 917978, 917979, 917980, 917981, 917982, 917983, 917984, 917985, 917986, 917987, 917988, 917989, 917990, 917991, 917992, 917993, 917994, 917995, 917996, 917997, 917998, 917999,
+}
+
+var verbose bool
+
+func main() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, `%s: Generate InvisibleRunesRange
+
+Usage: %[1]s [-v] [-o output.go]
+`, os.Args[0])
+ flag.PrintDefaults()
+ }
+
+ output := ""
+ flag.BoolVar(&verbose, "v", false, "verbose output")
+ flag.StringVar(&output, "o", "invisible_gen.go", "file to output to")
+ flag.Parse()
+
+ // First we filter the runes to remove
+ //
+ filtered := make([]rune, 0, len(InvisibleRunes))
+ for _, r := range InvisibleRunes {
+ if r == ' ' || r == '\t' || r == '\n' {
+ continue
+ }
+ filtered = append(filtered, r)
+ }
+
+ table := rangetable.New(filtered...)
+ if err := runTemplate(generatorTemplate, output, table); err != nil {
+ fatalf("Unable to run template: %v", err)
+ }
+}
+
+func runTemplate(t *template.Template, filename string, data interface{}) error {
+ buf := bytes.NewBuffer(nil)
+ if err := t.Execute(buf, data); err != nil {
+ return fmt.Errorf("unable to execute template: %w", err)
+ }
+ bs, err := format.Source(buf.Bytes())
+ if err != nil {
+ verbosef("Bad source:\n%s", buf.String())
+ return fmt.Errorf("unable to format source: %w", err)
+ }
+ file, err := os.Create(filename)
+ if err != nil {
+ return fmt.Errorf("failed to create file %s because %w", filename, err)
+ }
+ defer file.Close()
+ _, err = file.Write(bs)
+ if err != nil {
+ return fmt.Errorf("unable to write generated source: %w", err)
+ }
+ return nil
+}
+
+var generatorTemplate = template.Must(template.New("invisibleTemplate").Parse(`// This file is generated by modules/charset/invisible/generate.go DO NOT EDIT
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import "unicode"
+
+var InvisibleRanges = &unicode.RangeTable{
+ R16: []unicode.Range16{
+{{range .R16 }} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}},
+{{end}} },
+ R32: []unicode.Range32{
+{{range .R32}} {Lo:{{.Lo}}, Hi:{{.Hi}}, Stride: {{.Stride}}},
+{{end}} },
+ LatinOffset: {{.LatinOffset}},
+}
+`))
+
+func logf(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, format+"\n", args...)
+}
+
+func verbosef(format string, args ...interface{}) {
+ if verbose {
+ logf(format, args...)
+ }
+}
+
+func fatalf(format string, args ...interface{}) {
+ logf("fatal: "+format+"\n", args...)
+ os.Exit(1)
+}
diff --git a/modules/charset/invisible_gen.go b/modules/charset/invisible_gen.go
new file mode 100644
index 000000000000..b3bfebe0c0e0
--- /dev/null
+++ b/modules/charset/invisible_gen.go
@@ -0,0 +1,37 @@
+// This file is generated by modules/charset/invisible/generate.go DO NOT EDIT
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package charset
+
+import "unicode"
+
+var InvisibleRanges = &unicode.RangeTable{
+ R16: []unicode.Range16{
+ {Lo: 11, Hi: 13, Stride: 1},
+ {Lo: 127, Hi: 160, Stride: 33},
+ {Lo: 173, Hi: 847, Stride: 674},
+ {Lo: 1564, Hi: 4447, Stride: 2883},
+ {Lo: 4448, Hi: 6068, Stride: 1620},
+ {Lo: 6069, Hi: 6155, Stride: 86},
+ {Lo: 6156, Hi: 6158, Stride: 1},
+ {Lo: 7355, Hi: 7356, Stride: 1},
+ {Lo: 8192, Hi: 8207, Stride: 1},
+ {Lo: 8234, Hi: 8239, Stride: 1},
+ {Lo: 8287, Hi: 8303, Stride: 1},
+ {Lo: 10240, Hi: 12288, Stride: 2048},
+ {Lo: 12644, Hi: 65024, Stride: 52380},
+ {Lo: 65025, Hi: 65039, Stride: 1},
+ {Lo: 65279, Hi: 65440, Stride: 161},
+ {Lo: 65520, Hi: 65528, Stride: 1},
+ {Lo: 65532, Hi: 65532, Stride: 1},
+ },
+ R32: []unicode.Range32{
+ {Lo: 78844, Hi: 119155, Stride: 40311},
+ {Lo: 119156, Hi: 119162, Stride: 1},
+ {Lo: 917504, Hi: 917631, Stride: 1},
+ {Lo: 917760, Hi: 917999, Stride: 1},
+ },
+ LatinOffset: 2,
+}
diff --git a/modules/context/context.go b/modules/context/context.go
index 882491161992..0b9898acef04 100644
--- a/modules/context/context.go
+++ b/modules/context/context.go
@@ -224,7 +224,7 @@ func (ctx *Context) HTML(status int, name base.TplName) {
ctx.Data["TemplateLoadTimes"] = func() string {
return strconv.FormatInt(time.Since(tmplStartTime).Nanoseconds()/1e6, 10) + "ms"
}
- if err := ctx.Render.HTML(ctx.Resp, status, string(name), ctx.Data); err != nil {
+ if err := ctx.Render.HTML(ctx.Resp, status, string(name), templates.BaseVars().Merge(ctx.Data)); err != nil {
if status == http.StatusInternalServerError && name == base.TplName("status/500") {
ctx.PlainText(http.StatusInternalServerError, "Unable to find status/500 template")
return
diff --git a/modules/convert/git_commit_test.go b/modules/convert/git_commit_test.go
index 118ba3a007a2..0bba0e502e6d 100644
--- a/modules/convert/git_commit_test.go
+++ b/modules/convert/git_commit_test.go
@@ -19,7 +19,7 @@ import (
func TestToCommitMeta(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
sha1, _ := git.NewIDFromString("0000000000000000000000000000000000000000")
signature := &git.Signature{Name: "Test Signature", Email: "test@email.com", When: time.Unix(0, 0)}
tag := &git.Tag{
diff --git a/modules/convert/issue_test.go b/modules/convert/issue_test.go
index 5bf04bcb52b6..ec672abad277 100644
--- a/modules/convert/issue_test.go
+++ b/modules/convert/issue_test.go
@@ -21,8 +21,8 @@ import (
func TestLabel_ToLabel(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}).(*issues_model.Label)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID}).(*repo_model.Repository)
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: label.RepoID})
assert.Equal(t, &api.Label{
ID: label.ID,
Name: label.Name,
diff --git a/modules/convert/pull_test.go b/modules/convert/pull_test.go
index 10ef311399a6..a6ccbaca5897 100644
--- a/modules/convert/pull_test.go
+++ b/modules/convert/pull_test.go
@@ -20,8 +20,8 @@ import (
func TestPullRequest_APIFormat(t *testing.T) {
// with HeadRepo
assert.NoError(t, unittest.PrepareTestDatabase())
- headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ headRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadAttributes())
assert.NoError(t, pr.LoadIssue())
apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil)
@@ -35,7 +35,7 @@ func TestPullRequest_APIFormat(t *testing.T) {
}, apiPullRequest.Head)
// withOut HeadRepo
- pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1}).(*issues_model.PullRequest)
+ pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 1})
assert.NoError(t, pr.LoadIssue())
assert.NoError(t, pr.LoadAttributes())
// simulate fork deletion
diff --git a/modules/convert/user_test.go b/modules/convert/user_test.go
index 2ed962950fff..89d912e460c5 100644
--- a/modules/convert/user_test.go
+++ b/modules/convert/user_test.go
@@ -17,13 +17,13 @@ import (
func TestUser_ToUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true}).(*user_model.User)
+ user1 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1, IsAdmin: true})
apiUser := toUser(user1, true, true)
assert.True(t, apiUser.IsAdmin)
assert.Contains(t, apiUser.AvatarURL, "://")
- user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2, IsAdmin: false}).(*user_model.User)
+ user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2, IsAdmin: false})
apiUser = toUser(user2, true, true)
assert.False(t, apiUser.IsAdmin)
@@ -32,7 +32,7 @@ func TestUser_ToUser(t *testing.T) {
assert.False(t, apiUser.IsAdmin)
assert.EqualValues(t, api.VisibleTypePublic.String(), apiUser.Visibility)
- user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate}).(*user_model.User)
+ user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate})
apiUser = toUser(user31, true, true)
assert.False(t, apiUser.IsAdmin)
diff --git a/modules/doctor/doctor.go b/modules/doctor/doctor.go
index c8975a788e12..5d14cef55c9f 100644
--- a/modules/doctor/doctor.go
+++ b/modules/doctor/doctor.go
@@ -11,6 +11,7 @@ import (
"strings"
"code.gitea.io/gitea/models/db"
+ "code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
)
@@ -49,7 +50,11 @@ func initDBDisableConsole(ctx context.Context, disableConsole bool) error {
setting.NewXORMLogService(disableConsole)
if err := db.InitEngine(ctx); err != nil {
- return fmt.Errorf("models.SetEngine: %v", err)
+ return fmt.Errorf("db.InitEngine: %w", err)
+ }
+ // some doctor sub-commands need to use git command
+ if err := git.InitFull(ctx); err != nil {
+ return fmt.Errorf("git.InitFull: %w", err)
}
return nil
}
diff --git a/modules/doctor/mergebase.go b/modules/doctor/mergebase.go
index 2da91cdcc35f..46369290a13d 100644
--- a/modules/doctor/mergebase.go
+++ b/modules/doctor/mergebase.go
@@ -30,9 +30,6 @@ func iteratePRs(ctx context.Context, repo *repo_model.Repository, each func(*rep
}
func checkPRMergeBase(ctx context.Context, logger log.Logger, autofix bool) error {
- if err := git.InitOnceWithSync(ctx); err != nil {
- return err
- }
numRepos := 0
numPRs := 0
numPRsUpdated := 0
diff --git a/modules/doctor/misc.go b/modules/doctor/misc.go
index 24175fcaf4be..2d2bcb910db4 100644
--- a/modules/doctor/misc.go
+++ b/modules/doctor/misc.go
@@ -190,10 +190,6 @@ func checkDaemonExport(ctx context.Context, logger log.Logger, autofix bool) err
}
func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) error {
- if err := git.InitOnceWithSync(ctx); err != nil {
- return err
- }
-
numRepos := 0
numNeedUpdate := 0
numWritten := 0
diff --git a/modules/git/command.go b/modules/git/command.go
index a1bacbb707a2..b24d32dbe874 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -95,14 +95,15 @@ func (c *Command) AddArguments(args ...string) *Command {
return c
}
-// RunOpts represents parameters to run the command
+// RunOpts represents parameters to run the command. If UseContextTimeout is specified, then Timeout is ignored.
type RunOpts struct {
- Env []string
- Timeout time.Duration
- Dir string
- Stdout, Stderr io.Writer
- Stdin io.Reader
- PipelineFunc func(context.Context, context.CancelFunc) error
+ Env []string
+ Timeout time.Duration
+ UseContextTimeout bool
+ Dir string
+ Stdout, Stderr io.Writer
+ Stdin io.Reader
+ PipelineFunc func(context.Context, context.CancelFunc) error
}
func commonBaseEnvs() []string {
@@ -171,7 +172,15 @@ func (c *Command) Run(opts *RunOpts) error {
desc = fmt.Sprintf("%s %s [repo_path: %s]", c.name, strings.Join(args, " "), opts.Dir)
}
- ctx, cancel, finished := process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc)
+ var ctx context.Context
+ var cancel context.CancelFunc
+ var finished context.CancelFunc
+
+ if opts.UseContextTimeout {
+ ctx, cancel, finished = process.GetManager().AddContext(c.parentContext, desc)
+ } else {
+ ctx, cancel, finished = process.GetManager().AddContextTimeout(c.parentContext, opts.Timeout, desc)
+ }
defer finished()
cmd := exec.CommandContext(ctx, c.name, c.args...)
diff --git a/modules/git/git.go b/modules/git/git.go
index b8317396c015..99849f1f0945 100644
--- a/modules/git/git.go
+++ b/modules/git/git.go
@@ -15,7 +15,6 @@ import (
"regexp"
"runtime"
"strings"
- "sync"
"time"
"code.gitea.io/gitea/modules/log"
@@ -24,8 +23,8 @@ import (
"github.com/hashicorp/go-version"
)
-// GitVersionRequired is the minimum Git version required
-const GitVersionRequired = "2.0.0"
+// RequiredVersion is the minimum Git version required
+const RequiredVersion = "2.0.0"
var (
// GitExecutable is the command name of git
@@ -43,7 +42,7 @@ var (
// loadGitVersion returns current Git version from shell. Internal usage only.
func loadGitVersion() (*version.Version, error) {
- // doesn't need RWMutex because its exec by Init()
+ // doesn't need RWMutex because it's executed by Init()
if gitVersion != nil {
return gitVersion, nil
}
@@ -90,7 +89,7 @@ func SetExecutablePath(path string) error {
return fmt.Errorf("unable to load git version: %w", err)
}
- versionRequired, err := version.NewVersion(GitVersionRequired)
+ versionRequired, err := version.NewVersion(RequiredVersion)
if err != nil {
return err
}
@@ -104,7 +103,7 @@ func SetExecutablePath(path string) error {
moreHint = "get git: https://git-scm.com/download/linux and https://ius.io"
}
}
- return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), GitVersionRequired, moreHint)
+ return fmt.Errorf("installed git version %q is not supported, Gitea requires git version >= %q, %s", gitVersion.Original(), RequiredVersion, moreHint)
}
return nil
@@ -131,7 +130,7 @@ func checkInit() error {
return errors.New("unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
}
if DefaultContext != nil {
- log.Warn("git module has been initialized already, duplicate init should be fixed")
+ log.Warn("git module has been initialized already, duplicate init may work but it's better to fix it")
}
return nil
}
@@ -140,7 +139,7 @@ func checkInit() error {
func HomeDir() string {
if setting.Git.HomePath == "" {
// strict check, make sure the git module is initialized correctly.
- // attention: when the git module is called in gitea sub-command (serv/hook), the log module is not able to show messages to users.
+ // attention: when the git module is called in gitea sub-command (serv/hook), the log module might not obviously show messages to users/developers.
// for example: if there is gitea git hook code calling git.NewCommand before git.InitXxx, the integration test won't show the real failure reasons.
log.Fatal("Unable to init Git's HomeDir, incorrect initialization of the setting and git modules")
return ""
@@ -149,14 +148,14 @@ func HomeDir() string {
}
// InitSimple initializes git module with a very simple step, no config changes, no global command arguments.
-// This method doesn't change anything to filesystem. At the moment, it is only used by "git serv" sub-command, no data-race
-// However, in integration test, the sub-command function may be called in the current process, so the InitSimple would be called multiple times, too
+// This method doesn't change anything to filesystem. At the moment, it is only used by some Gitea sub-commands.
func InitSimple(ctx context.Context) error {
if err := checkInit(); err != nil {
return err
}
DefaultContext = ctx
+ globalCommandArgs = nil
if setting.Git.Timeout.Default > 0 {
defaultCommandExecutionTimeout = time.Duration(setting.Git.Timeout.Default) * time.Second
@@ -165,46 +164,46 @@ func InitSimple(ctx context.Context) error {
return SetExecutablePath(setting.Git.Path)
}
-var initOnce sync.Once
-
-// InitOnceWithSync initializes git module with version check and change global variables, sync gitconfig.
-// This method will update the global variables ONLY ONCE (just like git.CheckLFSVersion -- which is not ideal too),
-// otherwise there will be data-race problem at the moment.
-func InitOnceWithSync(ctx context.Context) (err error) {
+// InitFull initializes git module with version check and change global variables, sync gitconfig.
+// It should only be called once at the beginning of the program initialization (TestMain/GlobalInitInstalled) as this code makes unsynchronized changes to variables.
+func InitFull(ctx context.Context) (err error) {
if err = checkInit(); err != nil {
return err
}
- initOnce.Do(func() {
- if err = InitSimple(ctx); err != nil {
- return
- }
+ if err = InitSimple(ctx); err != nil {
+ return
+ }
- // when git works with gnupg (commit signing), there should be a stable home for gnupg commands
- if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
- _ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
- }
+ // when git works with gnupg (commit signing), there should be a stable home for gnupg commands
+ if _, ok := os.LookupEnv("GNUPGHOME"); !ok {
+ _ = os.Setenv("GNUPGHOME", filepath.Join(HomeDir(), ".gnupg"))
+ }
- // Since git wire protocol has been released from git v2.18
- if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
- globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
- }
+ // Since git wire protocol has been released from git v2.18
+ if setting.Git.EnableAutoGitWireProtocol && CheckGitVersionAtLeast("2.18") == nil {
+ globalCommandArgs = append(globalCommandArgs, "-c", "protocol.version=2")
+ }
- // By default partial clones are disabled, enable them from git v2.22
- if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
- globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true")
- }
+ // By default partial clones are disabled, enable them from git v2.22
+ if !setting.Git.DisablePartialClone && CheckGitVersionAtLeast("2.22") == nil {
+ globalCommandArgs = append(globalCommandArgs, "-c", "uploadpack.allowfilter=true", "-c", "uploadpack.allowAnySHA1InWant=true")
+ }
- // Explicitly disable credential helper, otherwise Git credentials might leak
- if CheckGitVersionAtLeast("2.9") == nil {
- globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
- }
+ // Explicitly disable credential helper, otherwise Git credentials might leak
+ if CheckGitVersionAtLeast("2.9") == nil {
+ globalCommandArgs = append(globalCommandArgs, "-c", "credential.helper=")
+ }
- SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
- })
- if err != nil {
- return err
+ SupportProcReceive = CheckGitVersionAtLeast("2.29") == nil
+
+ if setting.LFS.StartServer {
+ if CheckGitVersionAtLeast("2.1.2") != nil {
+ return errors.New("LFS server support requires Git >= 2.1.2")
+ }
+ globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=", "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
}
+
return syncGitConfig()
}
diff --git a/modules/git/git_test.go b/modules/git/git_test.go
index c5a63de0644c..091573787871 100644
--- a/modules/git/git_test.go
+++ b/modules/git/git_test.go
@@ -28,7 +28,7 @@ func testRun(m *testing.M) error {
defer util.RemoveAll(gitHomePath)
setting.Git.HomePath = gitHomePath
- if err = InitOnceWithSync(context.Background()); err != nil {
+ if err = InitFull(context.Background()); err != nil {
return fmt.Errorf("failed to call Init: %w", err)
}
diff --git a/modules/git/lfs.go b/modules/git/lfs.go
deleted file mode 100644
index c5d8354b6dc8..000000000000
--- a/modules/git/lfs.go
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright 2021 The Gitea Authors. All rights reserved.
-// Use of this source code is governed by a MIT-style
-// license that can be found in the LICENSE file.
-
-package git
-
-import (
- "sync"
-
- logger "code.gitea.io/gitea/modules/log"
- "code.gitea.io/gitea/modules/setting"
-)
-
-var once sync.Once
-
-// CheckLFSVersion will check lfs version, if not satisfied, then disable it.
-func CheckLFSVersion() {
- if setting.LFS.StartServer {
- // Disable LFS client hooks if installed for the current OS user
- // Needs at least git v2.1.2
- if CheckGitVersionAtLeast("2.1.2") != nil {
- setting.LFS.StartServer = false
- logger.Error("LFS server support needs at least Git v2.1.2")
- } else {
- once.Do(func() {
- globalCommandArgs = append(globalCommandArgs, "-c", "filter.lfs.required=",
- "-c", "filter.lfs.smudge=", "-c", "filter.lfs.clean=")
- })
- }
- }
-}
diff --git a/modules/git/repo_commit.go b/modules/git/repo_commit.go
index 7ff23af42eb8..d3731cb928e3 100644
--- a/modules/git/repo_commit.go
+++ b/modules/git/repo_commit.go
@@ -7,6 +7,8 @@ package git
import (
"bytes"
+ "encoding/hex"
+ "fmt"
"io"
"strconv"
"strings"
@@ -209,9 +211,9 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
}()
go func() {
stderr := strings.Builder{}
- err := NewCommand(repo.Ctx, "log", revision, "--follow",
+ err := NewCommand(repo.Ctx, "rev-list", revision,
"--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize*page),
- prettyLogFormat, "--", file).
+ "--skip="+strconv.Itoa(skip), "--", file).
Run(&RunOpts{
Dir: repo.Path,
Stdout: stdoutWriter,
@@ -224,32 +226,30 @@ func (repo *Repository) CommitsByFileAndRange(revision, file string, page int) (
}
}()
- if skip > 0 {
- _, err := io.CopyN(io.Discard, stdoutReader, int64(skip*41))
- if err != nil {
+ commits := []*Commit{}
+ shaline := [41]byte{}
+ var sha1 SHA1
+ for {
+ n, err := io.ReadFull(stdoutReader, shaline[:])
+ if err != nil || n < 40 {
if err == io.EOF {
- return []*Commit{}, nil
+ err = nil
}
- _ = stdoutReader.CloseWithError(err)
+ return commits, err
+ }
+ n, err = hex.Decode(sha1[:], shaline[0:40])
+ if n != 20 {
+ err = fmt.Errorf("invalid sha %q", string(shaline[:40]))
+ }
+ if err != nil {
return nil, err
}
+ commit, err := repo.getCommit(sha1)
+ if err != nil {
+ return nil, err
+ }
+ commits = append(commits, commit)
}
-
- stdout, err := io.ReadAll(stdoutReader)
- if err != nil {
- return nil, err
- }
- return repo.parsePrettyFormatLogToList(stdout)
-}
-
-// CommitsByFileAndRangeNoFollow return the commits according revision file and the page
-func (repo *Repository) CommitsByFileAndRangeNoFollow(revision, file string, page int) ([]*Commit, error) {
- stdout, _, err := NewCommand(repo.Ctx, "log", revision, "--skip="+strconv.Itoa((page-1)*50),
- "--max-count="+strconv.Itoa(setting.Git.CommitsRangeSize), prettyLogFormat, "--", file).RunStdBytes(&RunOpts{Dir: repo.Path})
- if err != nil {
- return nil, err
- }
- return repo.parsePrettyFormatLogToList(stdout)
}
// FilesCountBetween return the number of files changed between two commits
diff --git a/modules/graceful/net_unix.go b/modules/graceful/net_unix.go
index 680ff529af88..c7524a79dbc9 100644
--- a/modules/graceful/net_unix.go
+++ b/modules/graceful/net_unix.go
@@ -23,6 +23,7 @@ import (
const (
listenFDs = "LISTEN_FDS"
startFD = 3
+ unlinkFDs = "GITEA_UNLINK_FDS"
)
// In order to keep the working directory the same as when we started we record
@@ -33,8 +34,10 @@ var (
once = sync.Once{}
mutex = sync.Mutex{}
- providedListeners = []net.Listener{}
- activeListeners = []net.Listener{}
+ providedListenersToUnlink = []bool{}
+ activeListenersToUnlink = []bool{}
+ providedListeners = []net.Listener{}
+ activeListeners = []net.Listener{}
)
func getProvidedFDs() (savedErr error) {
@@ -53,6 +56,16 @@ func getProvidedFDs() (savedErr error) {
return
}
+ fdsToUnlinkStr := strings.Split(os.Getenv(unlinkFDs), ",")
+ providedListenersToUnlink = make([]bool, n)
+ for _, fdStr := range fdsToUnlinkStr {
+ i, err := strconv.Atoi(fdStr)
+ if err != nil || i < 0 || i >= n {
+ continue
+ }
+ providedListenersToUnlink[i] = true
+ }
+
for i := startFD; i < n+startFD; i++ {
file := os.NewFile(uintptr(i), fmt.Sprintf("listener_FD%d", i))
@@ -136,8 +149,11 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err
for i, l := range providedListeners {
if isSameAddr(l.Addr(), address) {
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
+ needsUnlink := providedListenersToUnlink[i]
+ providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
activeListeners = append(activeListeners, l)
+ activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
return l.(*net.TCPListener), nil
}
}
@@ -148,6 +164,7 @@ func GetListenerTCP(network string, address *net.TCPAddr) (*net.TCPListener, err
return nil, err
}
activeListeners = append(activeListeners, l)
+ activeListenersToUnlink = append(activeListenersToUnlink, false)
return l, nil
}
@@ -166,9 +183,15 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
for i, l := range providedListeners {
if isSameAddr(l.Addr(), address) {
providedListeners = append(providedListeners[:i], providedListeners[i+1:]...)
+ needsUnlink := providedListenersToUnlink[i]
+ providedListenersToUnlink = append(providedListenersToUnlink[:i], providedListenersToUnlink[i+1:]...)
+
+ activeListenersToUnlink = append(activeListenersToUnlink, needsUnlink)
activeListeners = append(activeListeners, l)
unixListener := l.(*net.UnixListener)
- unixListener.SetUnlinkOnClose(true)
+ if needsUnlink {
+ unixListener.SetUnlinkOnClose(true)
+ }
return unixListener, nil
}
}
@@ -189,6 +212,7 @@ func GetListenerUnix(network string, address *net.UnixAddr) (*net.UnixListener,
}
activeListeners = append(activeListeners, l)
+ activeListenersToUnlink = append(activeListenersToUnlink, true)
return l, nil
}
@@ -223,3 +247,11 @@ func getActiveListeners() []net.Listener {
copy(listeners, activeListeners)
return listeners
}
+
+func getActiveListenersToUnlink() []bool {
+ mutex.Lock()
+ defer mutex.Unlock()
+ listenersToUnlink := make([]bool, len(activeListenersToUnlink))
+ copy(listenersToUnlink, activeListenersToUnlink)
+ return listenersToUnlink
+}
diff --git a/modules/graceful/restart_unix.go b/modules/graceful/restart_unix.go
index 2654ddfb94d8..1d0d1059e9fd 100644
--- a/modules/graceful/restart_unix.go
+++ b/modules/graceful/restart_unix.go
@@ -12,6 +12,7 @@ import (
"net"
"os"
"os/exec"
+ "strconv"
"strings"
"sync"
"syscall"
@@ -75,6 +76,20 @@ func RestartProcess() (int, error) {
}
env = append(env, fmt.Sprintf("%s=%d", listenFDs, len(listeners)))
+ sb := &strings.Builder{}
+ for i, unlink := range getActiveListenersToUnlink() {
+ if !unlink {
+ continue
+ }
+ _, _ = sb.WriteString(strconv.Itoa(i))
+ _, _ = sb.WriteString(",")
+ }
+ unlinkStr := sb.String()
+ if len(unlinkStr) > 0 {
+ unlinkStr = unlinkStr[:len(unlinkStr)-1]
+ env = append(env, fmt.Sprintf("%s=%s", unlinkFDs, unlinkStr))
+ }
+
allFiles := append([]*os.File{os.Stdin, os.Stdout, os.Stderr}, files...)
process, err := os.StartProcess(argv0, os.Args, &os.ProcAttr{
Dir: originalWD,
diff --git a/modules/hostmatcher/hostmatcher.go b/modules/hostmatcher/hostmatcher.go
index 81c4202fcd98..a092e07f411a 100644
--- a/modules/hostmatcher/hostmatcher.go
+++ b/modules/hostmatcher/hostmatcher.go
@@ -78,6 +78,11 @@ func (hl *HostMatchList) AppendBuiltin(builtin string) {
hl.builtins = append(hl.builtins, builtin)
}
+// AppendPattern appends more pattern to match
+func (hl *HostMatchList) AppendPattern(pattern string) {
+ hl.patterns = append(hl.patterns, pattern)
+}
+
// IsEmpty checks if the checklist is empty
func (hl *HostMatchList) IsEmpty() bool {
return hl == nil || (len(hl.builtins) == 0 && len(hl.patterns) == 0 && len(hl.ipNets) == 0)
diff --git a/modules/mcaptcha/mcaptcha.go b/modules/mcaptcha/mcaptcha.go
new file mode 100644
index 000000000000..b889cf423b63
--- /dev/null
+++ b/modules/mcaptcha/mcaptcha.go
@@ -0,0 +1,27 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package mcaptcha
+
+import (
+ "context"
+ "fmt"
+
+ "code.gitea.io/gitea/modules/setting"
+
+ "codeberg.org/gusted/mcaptcha"
+)
+
+func Verify(ctx context.Context, token string) (bool, error) {
+ valid, err := mcaptcha.Verify(ctx, &mcaptcha.VerifyOpts{
+ InstanceURL: setting.Service.McaptchaURL,
+ Sitekey: setting.Service.McaptchaSitekey,
+ Secret: setting.Service.McaptchaSecret,
+ Token: token,
+ })
+ if err != nil {
+ return false, fmt.Errorf("wasn't able to verify mCaptcha: %v", err)
+ }
+ return valid, nil
+}
diff --git a/modules/notification/action/action_test.go b/modules/notification/action/action_test.go
index 2898c8ec3de4..f6de0d675959 100644
--- a/modules/notification/action/action_test.go
+++ b/modules/notification/action/action_test.go
@@ -26,8 +26,8 @@ func TestMain(m *testing.M) {
func TestRenameRepoAction(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID})
repo.Owner = user
oldRepoName := repo.Name
diff --git a/modules/packages/content_store.go b/modules/packages/content_store.go
index 64c3eedc2328..a3a5d1a6663c 100644
--- a/modules/packages/content_store.go
+++ b/modules/packages/content_store.go
@@ -27,21 +27,21 @@ func NewContentStore() *ContentStore {
// Get gets a package blob
func (s *ContentStore) Get(key BlobHash256Key) (storage.Object, error) {
- return s.store.Open(keyToRelativePath(key))
+ return s.store.Open(KeyToRelativePath(key))
}
// Save stores a package blob
func (s *ContentStore) Save(key BlobHash256Key, r io.Reader, size int64) error {
- _, err := s.store.Save(keyToRelativePath(key), r, size)
+ _, err := s.store.Save(KeyToRelativePath(key), r, size)
return err
}
// Delete deletes a package blob
func (s *ContentStore) Delete(key BlobHash256Key) error {
- return s.store.Delete(keyToRelativePath(key))
+ return s.store.Delete(KeyToRelativePath(key))
}
-// keyToRelativePath converts the sha256 key aabb000000... to aa/bb/aabb000000...
-func keyToRelativePath(key BlobHash256Key) string {
+// KeyToRelativePath converts the sha256 key aabb000000... to aa/bb/aabb000000...
+func KeyToRelativePath(key BlobHash256Key) string {
return path.Join(string(key)[0:2], string(key)[2:4], string(key))
}
diff --git a/modules/packages/hashed_buffer_test.go b/modules/packages/hashed_buffer_test.go
new file mode 100644
index 000000000000..e21ec67e1fed
--- /dev/null
+++ b/modules/packages/hashed_buffer_test.go
@@ -0,0 +1,47 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package packages
+
+import (
+ "fmt"
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestHashedBuffer(t *testing.T) {
+ cases := []struct {
+ MaxMemorySize int
+ Data string
+ HashMD5 string
+ HashSHA1 string
+ HashSHA256 string
+ HashSHA512 string
+ }{
+ {5, "test", "098f6bcd4621d373cade4e832627b4f6", "a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", "9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08", "ee26b0dd4af7e749aa1a8ee3c10ae9923f618980772e473f8819a5d4940e0db27ac185f8a0e1d5f84f88bc887fd67b143732c304cc5fa9ad8e6f57f50028a8ff"},
+ {5, "testtest", "05a671c66aefea124cc08b76ea6d30bb", "51abb9636078defbf888d8457a7c76f85c8f114c", "37268335dd6931045bdcdf92623ff819a64244b53d0e746d438797349d4da578", "125d6d03b32c84d492747f79cf0bf6e179d287f341384eb5d6d3197525ad6be8e6df0116032935698f99a09e265073d1d6c32c274591bf1d0a20ad67cba921bc"},
+ }
+
+ for _, c := range cases {
+ buf, err := CreateHashedBufferFromReader(strings.NewReader(c.Data), c.MaxMemorySize)
+ assert.NoError(t, err)
+
+ assert.EqualValues(t, len(c.Data), buf.Size())
+
+ data, err := io.ReadAll(buf)
+ assert.NoError(t, err)
+ assert.Equal(t, c.Data, string(data))
+
+ hashMD5, hashSHA1, hashSHA256, hashSHA512 := buf.Sums()
+ assert.Equal(t, c.HashMD5, fmt.Sprintf("%x", hashMD5))
+ assert.Equal(t, c.HashSHA1, fmt.Sprintf("%x", hashSHA1))
+ assert.Equal(t, c.HashSHA256, fmt.Sprintf("%x", hashSHA256))
+ assert.Equal(t, c.HashSHA512, fmt.Sprintf("%x", hashSHA512))
+
+ assert.NoError(t, buf.Close())
+ }
+}
diff --git a/modules/packages/pub/metadata.go b/modules/packages/pub/metadata.go
new file mode 100644
index 000000000000..1fc4908b9121
--- /dev/null
+++ b/modules/packages/pub/metadata.go
@@ -0,0 +1,154 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pub
+
+import (
+ "archive/tar"
+ "compress/gzip"
+ "errors"
+ "io"
+ "regexp"
+ "strings"
+
+ "code.gitea.io/gitea/modules/validation"
+
+ "github.com/hashicorp/go-version"
+ "gopkg.in/yaml.v2"
+)
+
+var (
+ ErrMissingPubspecFile = errors.New("Pubspec file is missing")
+ ErrPubspecFileTooLarge = errors.New("Pubspec file is too large")
+ ErrInvalidName = errors.New("Package name is invalid")
+ ErrInvalidVersion = errors.New("Package version is invalid")
+)
+
+var namePattern = regexp.MustCompile(`\A[a-zA-Z_][a-zA-Z0-9_]*\z`)
+
+// https://github.com/dart-lang/pub-dev/blob/4d582302a8d10152a5cd6129f65bf4f4dbca239d/pkg/pub_package_reader/lib/pub_package_reader.dart#L143
+const maxPubspecFileSize = 128 * 1024
+
+// Package represents a Pub package
+type Package struct {
+ Name string
+ Version string
+ Metadata *Metadata
+}
+
+// Metadata represents the metadata of a Pub package
+type Metadata struct {
+ Description string `json:"description,omitempty"`
+ ProjectURL string `json:"project_url,omitempty"`
+ RepositoryURL string `json:"repository_url,omitempty"`
+ DocumentationURL string `json:"documentation_url,omitempty"`
+ Readme string `json:"readme,omitempty"`
+ Pubspec interface{} `json:"pubspec"`
+}
+
+type pubspecPackage struct {
+ Name string `yaml:"name"`
+ Version string `yaml:"version"`
+ Description string `yaml:"description"`
+ Homepage string `yaml:"homepage"`
+ Repository string `yaml:"repository"`
+ Documentation string `yaml:"documentation"`
+}
+
+// ParsePackage parses the Pub package file
+func ParsePackage(r io.Reader) (*Package, error) {
+ gzr, err := gzip.NewReader(r)
+ if err != nil {
+ return nil, err
+ }
+ defer gzr.Close()
+
+ var p *Package
+ var readme string
+
+ tr := tar.NewReader(gzr)
+ for {
+ hd, err := tr.Next()
+ if err == io.EOF {
+ break
+ }
+ if err != nil {
+ return nil, err
+ }
+
+ if hd.Typeflag != tar.TypeReg {
+ continue
+ }
+
+ if hd.Name == "pubspec.yaml" {
+ if hd.Size > maxPubspecFileSize {
+ return nil, ErrPubspecFileTooLarge
+ }
+ p, err = ParsePubspecMetadata(tr)
+ if err != nil {
+ return nil, err
+ }
+ } else if strings.ToLower(hd.Name) == "readme.md" {
+ data, err := io.ReadAll(tr)
+ if err != nil {
+ return nil, err
+ }
+ readme = string(data)
+ }
+ }
+
+ if p == nil {
+ return nil, ErrMissingPubspecFile
+ }
+
+ p.Metadata.Readme = readme
+
+ return p, nil
+}
+
+// ParsePubspecMetadata parses a Pubspec file to retrieve the metadata of a Pub package
+func ParsePubspecMetadata(r io.Reader) (*Package, error) {
+ buf, err := io.ReadAll(io.LimitReader(r, maxPubspecFileSize))
+ if err != nil {
+ return nil, err
+ }
+
+ var p pubspecPackage
+ if err := yaml.Unmarshal(buf, &p); err != nil {
+ return nil, err
+ }
+
+ if !namePattern.MatchString(p.Name) {
+ return nil, ErrInvalidName
+ }
+
+ v, err := version.NewSemver(p.Version)
+ if err != nil {
+ return nil, ErrInvalidVersion
+ }
+
+ if !validation.IsValidURL(p.Homepage) {
+ p.Homepage = ""
+ }
+ if !validation.IsValidURL(p.Repository) {
+ p.Repository = ""
+ }
+
+ var pubspec interface{}
+ if err := yaml.Unmarshal(buf, &pubspec); err != nil {
+ return nil, err
+ }
+
+ return &Package{
+ Name: p.Name,
+ Version: v.String(),
+ Metadata: &Metadata{
+ Description: p.Description,
+ ProjectURL: p.Homepage,
+ RepositoryURL: p.Repository,
+ DocumentationURL: p.Documentation,
+ Pubspec: pubspec,
+ },
+ }, nil
+}
diff --git a/modules/packages/pub/metadata_test.go b/modules/packages/pub/metadata_test.go
new file mode 100644
index 000000000000..e43ed64fc6cd
--- /dev/null
+++ b/modules/packages/pub/metadata_test.go
@@ -0,0 +1,136 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pub
+
+import (
+ "archive/tar"
+ "bytes"
+ "compress/gzip"
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+const (
+ packageName = "gitea"
+ packageVersion = "1.0.1"
+ description = "Package Description"
+ projectURL = "https://gitea.io"
+ repositoryURL = "https://gitea.io/gitea/gitea"
+ documentationURL = "https://docs.gitea.io"
+)
+
+const pubspecContent = `name: ` + packageName + `
+version: ` + packageVersion + `
+description: ` + description + `
+homepage: ` + projectURL + `
+repository: ` + repositoryURL + `
+documentation: ` + documentationURL + `
+
+environment:
+ sdk: '>=2.16.0 <3.0.0'
+
+dependencies:
+ flutter:
+ sdk: flutter
+ path: '>=1.8.0 <3.0.0'
+
+dev_dependencies:
+ http: '>=0.13.0'`
+
+func TestParsePackage(t *testing.T) {
+ createArchive := func(files map[string][]byte) io.Reader {
+ var buf bytes.Buffer
+ zw := gzip.NewWriter(&buf)
+ tw := tar.NewWriter(zw)
+ for filename, content := range files {
+ hdr := &tar.Header{
+ Name: filename,
+ Mode: 0o600,
+ Size: int64(len(content)),
+ }
+ tw.WriteHeader(hdr)
+ tw.Write(content)
+ }
+ tw.Close()
+ zw.Close()
+ return &buf
+ }
+
+ t.Run("MissingPubspecFile", func(t *testing.T) {
+ data := createArchive(map[string][]byte{"dummy.txt": {}})
+
+ pp, err := ParsePackage(data)
+ assert.Nil(t, pp)
+ assert.ErrorIs(t, err, ErrMissingPubspecFile)
+ })
+
+ t.Run("PubspecFileTooLarge", func(t *testing.T) {
+ data := createArchive(map[string][]byte{"pubspec.yaml": make([]byte, 200*1024)})
+
+ pp, err := ParsePackage(data)
+ assert.Nil(t, pp)
+ assert.ErrorIs(t, err, ErrPubspecFileTooLarge)
+ })
+
+ t.Run("InvalidPubspecFile", func(t *testing.T) {
+ data := createArchive(map[string][]byte{"pubspec.yaml": {}})
+
+ pp, err := ParsePackage(data)
+ assert.Nil(t, pp)
+ assert.Error(t, err)
+ })
+
+ t.Run("Valid", func(t *testing.T) {
+ data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent)})
+
+ pp, err := ParsePackage(data)
+ assert.NoError(t, err)
+ assert.NotNil(t, pp)
+ assert.Empty(t, pp.Metadata.Readme)
+ })
+
+ t.Run("ValidWithReadme", func(t *testing.T) {
+ data := createArchive(map[string][]byte{"pubspec.yaml": []byte(pubspecContent), "README.md": []byte("readme")})
+
+ pp, err := ParsePackage(data)
+ assert.NoError(t, err)
+ assert.NotNil(t, pp)
+ assert.Equal(t, "readme", pp.Metadata.Readme)
+ })
+}
+
+func TestParsePubspecMetadata(t *testing.T) {
+ t.Run("InvalidName", func(t *testing.T) {
+ for _, name := range []string{"123abc", "ab-cd"} {
+ pp, err := ParsePubspecMetadata(strings.NewReader(`name: ` + name))
+ assert.Nil(t, pp)
+ assert.ErrorIs(t, err, ErrInvalidName)
+ }
+ })
+
+ t.Run("InvalidVersion", func(t *testing.T) {
+ pp, err := ParsePubspecMetadata(strings.NewReader(`name: dummy
+version: invalid`))
+ assert.Nil(t, pp)
+ assert.ErrorIs(t, err, ErrInvalidVersion)
+ })
+
+ t.Run("Valid", func(t *testing.T) {
+ pp, err := ParsePubspecMetadata(strings.NewReader(pubspecContent))
+ assert.NoError(t, err)
+ assert.NotNil(t, pp)
+
+ assert.Equal(t, packageName, pp.Name)
+ assert.Equal(t, packageVersion, pp.Version)
+ assert.Equal(t, description, pp.Metadata.Description)
+ assert.Equal(t, projectURL, pp.Metadata.ProjectURL)
+ assert.Equal(t, repositoryURL, pp.Metadata.RepositoryURL)
+ assert.Equal(t, documentationURL, pp.Metadata.DocumentationURL)
+ assert.NotNil(t, pp.Metadata.Pubspec)
+ })
+}
diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go
index 37181d2dcd0d..c62e324b66fe 100644
--- a/modules/repository/commits_test.go
+++ b/modules/repository/commits_test.go
@@ -49,7 +49,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) {
}
pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"}
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16})
payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo.RepoPath(), "/user2/repo16")
assert.NoError(t, err)
assert.Len(t, payloadCommits, 3)
diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go
index 2a47e9363149..39f8b11356de 100644
--- a/modules/repository/create_test.go
+++ b/modules/repository/create_test.go
@@ -24,7 +24,7 @@ func TestIncludesAllRepositoriesTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testTeamRepositories := func(teamID int64, repoIds []int64) {
- team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID}).(*organization.Team)
+ team := unittest.AssertExistsAndLoadBean(t, &organization.Team{ID: teamID})
assert.NoError(t, team.GetRepositoriesCtx(db.DefaultContext), "%s: GetRepositories", team.Name)
assert.Len(t, team.Repos, team.NumRepos, "%s: len repo", team.Name)
assert.Len(t, team.Repos, len(repoIds), "%s: repo count", team.Name)
diff --git a/modules/repository/hooks.go b/modules/repository/hooks.go
index c2eb3a7c75f7..7bc77552bd05 100644
--- a/modules/repository/hooks.go
+++ b/modules/repository/hooks.go
@@ -8,6 +8,7 @@ import (
"fmt"
"os"
"path/filepath"
+ "runtime"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/setting"
@@ -153,6 +154,10 @@ func createDelegateHooks(repoPath string) (err error) {
}
func checkExecutable(filename string) bool {
+ // windows has no concept of a executable bit
+ if runtime.GOOS == "windows" {
+ return true
+ }
fileInfo, err := os.Stat(filename)
if err != nil {
return false
diff --git a/modules/setting/service.go b/modules/setting/service.go
index bd97e10b0f0d..10e389995032 100644
--- a/modules/setting/service.go
+++ b/modules/setting/service.go
@@ -38,6 +38,7 @@ var Service = struct {
EnableReverseProxyAuth bool
EnableReverseProxyAutoRegister bool
EnableReverseProxyEmail bool
+ EnableReverseProxyFullName bool
EnableCaptcha bool
RequireExternalRegistrationCaptcha bool
RequireExternalRegistrationPassword bool
@@ -47,6 +48,9 @@ var Service = struct {
RecaptchaURL string
HcaptchaSecret string
HcaptchaSitekey string
+ McaptchaSecret string
+ McaptchaSitekey string
+ McaptchaURL string
DefaultKeepEmailPrivate bool
DefaultAllowCreateOrganization bool
DefaultUserIsRestricted bool
@@ -124,6 +128,7 @@ func newService() {
Service.EnableReverseProxyAuth = sec.Key("ENABLE_REVERSE_PROXY_AUTHENTICATION").MustBool()
Service.EnableReverseProxyAutoRegister = sec.Key("ENABLE_REVERSE_PROXY_AUTO_REGISTRATION").MustBool()
Service.EnableReverseProxyEmail = sec.Key("ENABLE_REVERSE_PROXY_EMAIL").MustBool()
+ Service.EnableReverseProxyFullName = sec.Key("ENABLE_REVERSE_PROXY_FULL_NAME").MustBool()
Service.EnableCaptcha = sec.Key("ENABLE_CAPTCHA").MustBool(false)
Service.RequireExternalRegistrationCaptcha = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_CAPTCHA").MustBool(Service.EnableCaptcha)
Service.RequireExternalRegistrationPassword = sec.Key("REQUIRE_EXTERNAL_REGISTRATION_PASSWORD").MustBool()
@@ -133,6 +138,9 @@ func newService() {
Service.RecaptchaURL = sec.Key("RECAPTCHA_URL").MustString("https://www.google.com/recaptcha/")
Service.HcaptchaSecret = sec.Key("HCAPTCHA_SECRET").MustString("")
Service.HcaptchaSitekey = sec.Key("HCAPTCHA_SITEKEY").MustString("")
+ Service.McaptchaURL = sec.Key("MCAPTCHA_URL").MustString("https://demo.mcaptcha.org/")
+ Service.McaptchaSecret = sec.Key("MCAPTCHA_SECRET").MustString("")
+ Service.McaptchaSitekey = sec.Key("MCAPTCHA_SITEKEY").MustString("")
Service.DefaultKeepEmailPrivate = sec.Key("DEFAULT_KEEP_EMAIL_PRIVATE").MustBool()
Service.DefaultAllowCreateOrganization = sec.Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").MustBool(true)
Service.DefaultUserIsRestricted = sec.Key("DEFAULT_USER_IS_RESTRICTED").MustBool(false)
diff --git a/modules/setting/setting.go b/modules/setting/setting.go
index 23e3280dc9f1..3ab25fef6ea8 100644
--- a/modules/setting/setting.go
+++ b/modules/setting/setting.go
@@ -59,6 +59,7 @@ const (
ImageCaptcha = "image"
ReCaptcha = "recaptcha"
HCaptcha = "hcaptcha"
+ MCaptcha = "mcaptcha"
)
// settings
@@ -185,6 +186,7 @@ var (
CookieRememberName string
ReverseProxyAuthUser string
ReverseProxyAuthEmail string
+ ReverseProxyAuthFullName string
ReverseProxyLimit int
ReverseProxyTrustedProxies []string
MinPasswordLength int
@@ -262,8 +264,8 @@ var (
}{
ExplorePagingNum: 20,
SitemapPagingNum: 20,
- IssuePagingNum: 10,
- RepoSearchPagingNum: 10,
+ IssuePagingNum: 20,
+ RepoSearchPagingNum: 20,
MembersPagingNum: 20,
FeedMaxCommitNum: 5,
FeedPagingNum: 20,
@@ -908,6 +910,7 @@ func loadFromConf(allowEmpty bool, extraConfig string) {
ReverseProxyAuthUser = sec.Key("REVERSE_PROXY_AUTHENTICATION_USER").MustString("X-WEBAUTH-USER")
ReverseProxyAuthEmail = sec.Key("REVERSE_PROXY_AUTHENTICATION_EMAIL").MustString("X-WEBAUTH-EMAIL")
+ ReverseProxyAuthFullName = sec.Key("REVERSE_PROXY_AUTHENTICATION_FULL_NAME").MustString("X-WEBAUTH-FULLNAME")
ReverseProxyLimit = sec.Key("REVERSE_PROXY_LIMIT").MustInt(1)
ReverseProxyTrustedProxies = sec.Key("REVERSE_PROXY_TRUSTED_PROXIES").Strings(",")
diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go
index bffe29f4c385..6b601c008fe9 100644
--- a/modules/ssh/ssh.go
+++ b/modules/ssh/ssh.go
@@ -75,11 +75,20 @@ func sessionHandler(session ssh.Session) {
ctx, cancel := context.WithCancel(session.Context())
defer cancel()
+ gitProtocol := ""
+ for _, env := range session.Environ() {
+ if strings.HasPrefix(env, "GIT_PROTOCOL=") {
+ _, gitProtocol, _ = strings.Cut(env, "=")
+ break
+ }
+ }
+
cmd := exec.CommandContext(ctx, setting.AppPath, args...)
cmd.Env = append(
os.Environ(),
"SSH_ORIGINAL_COMMAND="+command,
"SKIP_MINWINSVC=1",
+ "GIT_PROTOCOL="+gitProtocol,
)
stdout, err := cmd.StdoutPipe()
diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index 8a15cec2c68a..602afec4135f 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -972,11 +972,11 @@ type remoteAddress struct {
Password string
}
-func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string) remoteAddress {
+func mirrorRemoteAddress(ctx context.Context, m *repo_model.Repository, remoteName string, ignoreOriginalURL bool) remoteAddress {
a := remoteAddress{}
remoteURL := m.OriginalURL
- if remoteURL == "" {
+ if ignoreOriginalURL || remoteURL == "" {
var err error
remoteURL, err = git.GetRemoteAddress(ctx, m.RepoPath(), remoteName)
if err != nil {
diff --git a/modules/test/context_tests.go b/modules/test/context_tests.go
index a08439e93f4c..963f79c3c6b1 100644
--- a/modules/test/context_tests.go
+++ b/modules/test/context_tests.go
@@ -56,7 +56,7 @@ func MockContext(t *testing.T, path string) *context.Context {
// LoadRepo load a repo into a test context.
func LoadRepo(t *testing.T, ctx *context.Context, repoID int64) {
ctx.Repo = &context.Repository{}
- ctx.Repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID}).(*repo_model.Repository)
+ ctx.Repo.Repository = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repoID})
var err error
ctx.Repo.Owner, err = user_model.GetUserByID(ctx.Repo.Repository.OwnerID)
assert.NoError(t, err)
@@ -81,7 +81,7 @@ func LoadRepoCommit(t *testing.T, ctx *context.Context) {
// LoadUser load a user into a test context.
func LoadUser(t *testing.T, ctx *context.Context, userID int64) {
- ctx.Doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User)
+ ctx.Doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
}
// LoadGitRepo load a git repo into a test context. Requires that ctx.Repo has
diff --git a/modules/timeutil/since.go b/modules/timeutil/since.go
index 5e89b0faa29a..8473d450510c 100644
--- a/modules/timeutil/since.go
+++ b/modules/timeutil/since.go
@@ -234,7 +234,7 @@ func TimeSince(then time.Time, lang translation.Locale) template.HTML {
}
func htmlTimeSince(then, now time.Time, lang translation.Locale) template.HTML {
- return template.HTML(fmt.Sprintf(`%s `,
+ return template.HTML(fmt.Sprintf(`%s `,
then.In(setting.DefaultUILocation).Format(GetTimeFormat(lang.Language())),
timeSince(then, now, lang)))
}
@@ -245,7 +245,7 @@ func TimeSinceUnix(then TimeStamp, lang translation.Locale) template.HTML {
}
func htmlTimeSinceUnix(then, now TimeStamp, lang translation.Locale) template.HTML {
- return template.HTML(fmt.Sprintf(`%s `,
+ return template.HTML(fmt.Sprintf(`%s `,
then.FormatInLocation(GetTimeFormat(lang.Language()), setting.DefaultUILocation),
timeSinceUnix(int64(then), int64(now), lang)))
}
diff --git a/modules/timeutil/since_test.go b/modules/timeutil/since_test.go
index 8bdb9d7546a3..dfcf9cb01d98 100644
--- a/modules/timeutil/since_test.go
+++ b/modules/timeutil/since_test.go
@@ -119,7 +119,7 @@ func TestHtmlTimeSince(t *testing.T) {
// test that `diff` yields a result containing `expected`
test := func(expected string, diff time.Duration) {
actual := htmlTimeSince(BaseDate, BaseDate.Add(diff), translation.NewLocale("en-US"))
- assert.Contains(t, actual, `title="Sat Jan 1 00:00:00 UTC 2000"`)
+ assert.Contains(t, actual, `data-content="Sat Jan 1 00:00:00 UTC 2000"`)
assert.Contains(t, actual, expected)
}
test("1 second", time.Second)
diff --git a/modules/util/filebuffer/file_backed_buffer.go b/modules/util/filebuffer/file_backed_buffer.go
index 128030b4c5c1..8e3e138e04b7 100644
--- a/modules/util/filebuffer/file_backed_buffer.go
+++ b/modules/util/filebuffer/file_backed_buffer.go
@@ -103,35 +103,45 @@ func (b *FileBackedBuffer) Size() int64 {
return b.size
}
-func (b *FileBackedBuffer) switchToReader() {
+func (b *FileBackedBuffer) switchToReader() error {
if b.reader != nil {
- return
+ return nil
}
if b.file != nil {
+ if _, err := b.file.Seek(0, io.SeekStart); err != nil {
+ return err
+ }
b.reader = b.file
} else {
b.reader = bytes.NewReader(b.buffer.Bytes())
}
+ return nil
}
// Read implements io.Reader
func (b *FileBackedBuffer) Read(p []byte) (int, error) {
- b.switchToReader()
+ if err := b.switchToReader(); err != nil {
+ return 0, err
+ }
return b.reader.Read(p)
}
// ReadAt implements io.ReaderAt
func (b *FileBackedBuffer) ReadAt(p []byte, off int64) (int, error) {
- b.switchToReader()
+ if err := b.switchToReader(); err != nil {
+ return 0, err
+ }
return b.reader.ReadAt(p, off)
}
// Seek implements io.Seeker
func (b *FileBackedBuffer) Seek(offset int64, whence int) (int64, error) {
- b.switchToReader()
+ if err := b.switchToReader(); err != nil {
+ return 0, err
+ }
return b.reader.Seek(offset, whence)
}
diff --git a/modules/util/filebuffer/file_backed_buffer_test.go b/modules/util/filebuffer/file_backed_buffer_test.go
new file mode 100644
index 000000000000..83ef58561de5
--- /dev/null
+++ b/modules/util/filebuffer/file_backed_buffer_test.go
@@ -0,0 +1,36 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package filebuffer
+
+import (
+ "io"
+ "strings"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestFileBackedBuffer(t *testing.T) {
+ cases := []struct {
+ MaxMemorySize int
+ Data string
+ }{
+ {5, "test"},
+ {5, "testtest"},
+ }
+
+ for _, c := range cases {
+ buf, err := CreateFromReader(strings.NewReader(c.Data), c.MaxMemorySize)
+ assert.NoError(t, err)
+
+ assert.EqualValues(t, len(c.Data), buf.Size())
+
+ data, err := io.ReadAll(buf)
+ assert.NoError(t, err)
+ assert.Equal(t, c.Data, string(data))
+
+ assert.NoError(t, buf.Close())
+ }
+}
diff --git a/modules/util/sec_to_time.go b/modules/util/sec_to_time.go
index 9ce6fe1a13eb..13461915e6f3 100644
--- a/modules/util/sec_to_time.go
+++ b/modules/util/sec_to_time.go
@@ -18,10 +18,22 @@ import (
// 45677465s -> 1 year 6 months
func SecToTime(duration int64) string {
formattedTime := ""
- years := duration / (3600 * 24 * 7 * 4 * 12)
- months := (duration / (3600 * 24 * 30)) % 12
- weeks := (duration / (3600 * 24 * 7)) % 4
- days := (duration / (3600 * 24)) % 7
+
+ // The following four variables are calculated by taking
+ // into account the previously calculated variables, this avoids
+ // pitfalls when using remainders. As that could lead to incorrect
+ // results when the calculated number equals the quotient number.
+ remainingDays := duration / (60 * 60 * 24)
+ years := remainingDays / 365
+ remainingDays -= years * 365
+ months := remainingDays * 12 / 365
+ remainingDays -= months * 365 / 12
+ weeks := remainingDays / 7
+ remainingDays -= weeks * 7
+ days := remainingDays
+
+ // The following three variables are calculated without depending
+ // on the previous calculated variables.
hours := (duration / 3600) % 24
minutes := (duration / 60) % 60
seconds := duration % 60
diff --git a/modules/util/sec_to_time_test.go b/modules/util/sec_to_time_test.go
index 854190462bc3..1e256aa8650c 100644
--- a/modules/util/sec_to_time_test.go
+++ b/modules/util/sec_to_time_test.go
@@ -11,10 +11,21 @@ import (
)
func TestSecToTime(t *testing.T) {
- assert.Equal(t, SecToTime(66), "1 minute 6 seconds")
- assert.Equal(t, SecToTime(52410), "14 hours 33 minutes")
- assert.Equal(t, SecToTime(563418), "6 days 12 hours")
- assert.Equal(t, SecToTime(1563418), "2 weeks 4 days")
- assert.Equal(t, SecToTime(3937125), "1 month 2 weeks")
- assert.Equal(t, SecToTime(45677465), "1 year 5 months")
+ second := int64(1)
+ minute := 60 * second
+ hour := 60 * minute
+ day := 24 * hour
+ year := 365 * day
+
+ assert.Equal(t, "1 minute 6 seconds", SecToTime(minute+6*second))
+ assert.Equal(t, "1 hour", SecToTime(hour))
+ assert.Equal(t, "1 hour", SecToTime(hour+second))
+ assert.Equal(t, "14 hours 33 minutes", SecToTime(14*hour+33*minute+30*second))
+ assert.Equal(t, "6 days 12 hours", SecToTime(6*day+12*hour+30*minute+18*second))
+ assert.Equal(t, "2 weeks 4 days", SecToTime((2*7+4)*day+2*hour+16*minute+58*second))
+ assert.Equal(t, "4 weeks", SecToTime(4*7*day))
+ assert.Equal(t, "4 weeks 1 day", SecToTime((4*7+1)*day))
+ assert.Equal(t, "1 month 2 weeks", SecToTime((6*7+3)*day+13*hour+38*minute+45*second))
+ assert.Equal(t, "11 months", SecToTime(year-25*day))
+ assert.Equal(t, "1 year 5 months", SecToTime(year+163*day+10*hour+11*minute+5*second))
}
diff --git a/modules/web/middleware/binding.go b/modules/web/middleware/binding.go
index 88a3920f6e67..636e655b9e95 100644
--- a/modules/web/middleware/binding.go
+++ b/modules/web/middleware/binding.go
@@ -136,7 +136,16 @@ func Validate(errs binding.Errors, data map[string]interface{}, f Form, l transl
case validation.ErrRegexPattern:
data["ErrorMsg"] = trName + l.Tr("form.regex_pattern_error", errs[0].Message)
default:
- data["ErrorMsg"] = l.Tr("form.unknown_error") + " " + errs[0].Classification
+ msg := errs[0].Classification
+ if msg != "" && errs[0].Message != "" {
+ msg += ": "
+ }
+
+ msg += errs[0].Message
+ if msg == "" {
+ msg = l.Tr("form.unknown_error")
+ }
+ data["ErrorMsg"] = trName + ": " + msg
}
return errs
}
diff --git a/options/license/CC-BY-3.0-IGO b/options/license/CC-BY-3.0-IGO
new file mode 100644
index 000000000000..13ab9536e179
--- /dev/null
+++ b/options/license/CC-BY-3.0-IGO
@@ -0,0 +1,101 @@
+Creative Commons Attribution 3.0 IGO
+
+CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS LICENSE DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE INFORMATION PROVIDED, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM ITS USE. THE LICENSOR IS NOT NECESSARILY AN INTERGOVERNMENTAL ORGANIZATION (IGO), AS DEFINED IN THE LICENSE BELOW.
+
+License
+
+THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("LICENSE"). THE LICENSOR (DEFINED BELOW) HOLDS COPYRIGHT AND OTHER RIGHTS IN THE WORK. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE IS PROHIBITED.
+
+BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION FOR YOUR ACCEPTANCE AND AGREEMENT TO THE TERMS OF THE LICENSE.
+
+1. Definitions
+
+ a. "IGO" means, solely and exclusively for purposes of this License, an organization established by a treaty or other instrument governed by international law and possessing its own international legal personality. Other organizations established to carry out activities across national borders and that accordingly enjoy immunity from legal process are also IGOs for the sole and exclusive purposes of this License. IGOs may include as members, in addition to states, other entities.
+
+ b. "Work" means the literary and/or artistic work eligible for copyright protection, whatever may be the mode or form of its expression including digital form, and offered under the terms of this License. It is understood that a database, which by reason of the selection and arrangement of its contents constitutes an intellectual creation, is considered a Work.
+
+ c. "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License and may be, but is not necessarily, an IGO.
+
+ d. "You" means an individual or entity exercising rights under this License.
+
+ e. "Reproduce" means to make a copy of the Work in any manner or form, and by any means.
+
+ f. "Distribute" means the activity of making publicly available the Work or Adaptation (or copies of the Work or Adaptation), as applicable, by sale, rental, public lending or any other known form of transfer of ownership or possession of the Work or copy of the Work.
+
+ g. "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images.
+
+ h. "Adaptation" means a work derived from or based upon the Work, or upon the Work and other pre-existing works. Adaptations may include works such as translations, derivative works, or any alterations and arrangements of any kind involving the Work. For purposes of this License, where the Work is a musical work, performance, or phonogram, the synchronization of the Work in timed-relation with a moving image is an Adaptation. For the avoidance of doubt, including the Work in a Collection is not an Adaptation.
+
+ i. "Collection" means a collection of literary or artistic works or other works or subject matter other than works listed in Section 1(b) which by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. For the avoidance of doubt, a Collection will not be considered as an Adaptation.
+
+2. Scope of this License. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright protection.
+
+3. License Grant. Subject to the terms and conditions of this License, the Licensor hereby grants You a worldwide, royalty-free, non-exclusive license to exercise the rights in the Work as follows:
+
+ a. to Reproduce, Distribute and Publicly Perform the Work, to incorporate the Work into one or more Collections, and to Reproduce, Distribute and Publicly Perform the Work as incorporated in the Collections; and,
+
+ b. to create, Reproduce, Distribute and Publicly Perform Adaptations, provided that You clearly label, demarcate or otherwise identify that changes were made to the original Work.
+
+ c. For the avoidance of doubt:
+
+ i. Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License;
+
+ ii. Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor waives the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; and,
+
+ iii. Voluntary License Schemes. To the extent possible, the Licensor waives the right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary licensing scheme.
+
+This License lasts for the duration of the term of the copyright in the Work licensed by the Licensor. The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. All rights not expressly granted by the Licensor are hereby reserved.
+
+4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions:
+
+ a. You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work (see section 8(a)). You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from a Licensor You must, to the extent practicable, remove from the Collection any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested. If You create an Adaptation, upon notice from a Licensor You must, to the extent practicable, remove from the Adaptation any credit (inclusive of any logo, trademark, official mark or official emblem) as required by Section 4(b), as requested.
+
+ b. If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) any attributions that the Licensor indicates be associated with the Work as indicated in a copyright notice, (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that the Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation. The credit required by this Section 4(b) may be implemented in any reasonable manner; provided, however, that in the case of an Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributors to the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Licensor or others designated for attribution, of You or Your use of the Work, without the separate, express prior written permission of the Licensor or such others.
+
+ c. Except as otherwise agreed in writing by the Licensor, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the honor or reputation of the Licensor where moral rights apply.
+
+5. Representations, Warranties and Disclaimer
+
+THE LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE.
+
+6. Limitation on Liability
+
+IN NO EVENT WILL THE LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF THE LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+7. Termination
+
+ a. Subject to the terms and conditions set forth in this License, the license granted here lasts for the duration of the term of the copyright in the Work licensed by the Licensor as stated in Section 3. Notwithstanding the above, the Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated below.
+
+ b. If You fail to comply with this License, then this License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. Notwithstanding the foregoing, this License reinstates automatically as of the date the violation is cured, provided it is cured within 30 days of You discovering the violation, or upon express reinstatement by the Licensor. For the avoidance of doubt, this Section 7(b) does not affect any rights the Licensor may have to seek remedies for violations of this License by You.
+
+8. Miscellaneous
+
+ a. Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License.
+
+ b. Each time You Distribute or Publicly Perform an Adaptation, the Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License.
+
+ c. If any provision of this License is invalid or unenforceable, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable.
+
+ d. No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the Licensor.
+
+ e. This License constitutes the entire agreement between You and the Licensor with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. The Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You.
+
+ f. The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). Interpretation of the scope of the rights granted by the Licensor and the conditions imposed on You under this License, this License, and the rights and conditions set forth herein shall be made with reference to copyright as determined in accordance with general principles of international law, including the above mentioned conventions.
+
+ g. Nothing in this License constitutes or may be interpreted as a limitation upon or waiver of any privileges and immunities that may apply to the Licensor or You, including immunity from the legal processes of any jurisdiction, national court or other authority.
+
+ h. Where the Licensor is an IGO, any and all disputes arising under this License that cannot be settled amicably shall be resolved in accordance with the following procedure:
+
+ i. Pursuant to a notice of mediation communicated by reasonable means by either You or the Licensor to the other, the dispute shall be submitted to non-binding mediation conducted in accordance with rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with those communicated in the notice of mediation. The language used in the mediation proceedings shall be English unless otherwise agreed.
+
+ ii. If any such dispute has not been settled within 45 days following the date on which the notice of mediation is provided, either You or the Licensor may, pursuant to a notice of arbitration communicated by reasonable means to the other, elect to have the dispute referred to and finally determined by arbitration. The arbitration shall be conducted in accordance with the rules designated by the Licensor in the copyright notice published with the Work, or if none then in accordance with the UNCITRAL Arbitration Rules as then in force. The arbitral tribunal shall consist of a sole arbitrator and the language of the proceedings shall be English unless otherwise agreed. The place of arbitration shall be where the Licensor has its headquarters. The arbitral proceedings shall be conducted remotely (e.g., via telephone conference or written submissions) whenever practicable.
+
+ iii. Interpretation of this License in any dispute submitted to mediation or arbitration shall be as set forth in Section 8(f), above.
+
+Creative Commons Notice
+
+Creative Commons is not a party to this License, and makes no warranty whatsoever in connection with the Work. Creative Commons will not be liable to You or any party on any legal theory for any damages whatsoever, including without limitation any general, special, incidental or consequential damages arising in connection to this license. Notwithstanding the foregoing two (2) sentences, if Creative Commons has expressly identified itself as the Licensor hereunder, it shall have all rights and obligations of the Licensor.
+
+Except for the limited purpose of indicating to the public that the Work is licensed under the CCPL, Creative Commons does not authorize the use by either party of the trademark "Creative Commons" or any related trademark or logo of Creative Commons without the prior written consent of Creative Commons. Any permitted use will be in compliance with Creative Commons' then-current trademark usage guidelines, as may be published on its website or otherwise made available upon request from time to time. For the avoidance of doubt, this trademark restriction does not form part of this License.
+
+Creative Commons may be contacted at https://creativecommons.org/.
diff --git a/options/license/LZMA-SDK-9.11-to-9.20 b/options/license/LZMA-SDK-9.11-to-9.20
new file mode 100644
index 000000000000..5da25bf883ce
--- /dev/null
+++ b/options/license/LZMA-SDK-9.11-to-9.20
@@ -0,0 +1,8 @@
+LICENSE
+-------
+
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+Some code in LZMA is based on public domain code from another developers:
+ 1) PPMd var.H (2001): Dmitry Shkarin
+ 2) SHA-256: Wei Dai (Crypto++ library)
diff --git a/options/license/LZMA-SDK-9.22 b/options/license/LZMA-SDK-9.22
new file mode 100644
index 000000000000..ef4768d2a722
--- /dev/null
+++ b/options/license/LZMA-SDK-9.22
@@ -0,0 +1,15 @@
+LICENSE
+-------
+
+LZMA SDK is written and placed in the public domain by Igor Pavlov.
+
+Some code in LZMA SDK is based on public domain code from another developers:
+ 1) PPMd var.H (2001): Dmitry Shkarin
+ 2) SHA-256: Wei Dai (Crypto++ library)
+
+Anyone is free to copy, modify, publish, use, compile, sell, or distribute the
+original LZMA SDK code, either in source code form or as a compiled binary, for
+any purpose, commercial or non-commercial, and by any means.
+
+LZMA SDK code is compatible with open source licenses, for example, you can
+include it to GNU GPL or GNU LGPL code.
diff --git a/options/license/NICTA-1.0 b/options/license/NICTA-1.0
new file mode 100644
index 000000000000..04622e308d1a
--- /dev/null
+++ b/options/license/NICTA-1.0
@@ -0,0 +1,61 @@
+NICTA Public Software Licence
+Version 1.0
+
+Copyright © 2004 National ICT Australia Ltd
+
+All rights reserved.
+
+By this licence, National ICT Australia Ltd (NICTA) grants permission,
+free of charge, to any person who obtains a copy of this software
+and any associated documentation files ("the Software") to use and
+deal with the Software in source code and binary forms without
+restriction, with or without modification, and to permit persons
+to whom the Software is furnished to do so, provided that the
+following conditions are met:
+
+- Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimers.
+- Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimers in
+ the documentation and/or other materials provided with the
+ distribution.
+- The name of NICTA may not be used to endorse or promote products
+ derived from this Software without specific prior written permission.
+
+EXCEPT AS EXPRESSLY STATED IN THIS LICENCE AND TO THE FULL EXTENT
+PERMITTED BY APPLICABLE LAW, THE SOFTWARE IS PROVIDED "AS-IS" AND
+NICTA MAKES NO REPRESENTATIONS, WARRANTIES OR CONDITIONS OF ANY
+KIND, EXPRESS OR IMPLIED, INCLUDING, WITHOUT LIMITATION, ANY
+REPRESENTATIONS, WARRANTIES OR CONDITIONS REGARDING THE CONTENTS
+OR ACCURACY OF THE SOFTWARE, OR OF TITLE, MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, THE ABSENCE OF LATENT
+OR OTHER DEFECTS, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR
+NOT DISCOVERABLE.
+
+TO THE FULL EXTENT PERMITTED BY APPLICABLE LAW, IN NO EVENT WILL
+NICTA BE LIABLE ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION,
+NEGLIGENCE) FOR ANY LOSS OR DAMAGE WHATSOEVER, INCLUDING (WITHOUT
+LIMITATION) LOSS OF PRODUCTION OR OPERATION TIME, LOSS, DAMAGE OR
+CORRUPTION OF DATA OR RECORDS; OR LOSS OF ANTICIPATED SAVINGS,
+OPPORTUNITY, REVENUE, PROFIT OR GOODWILL, OR OTHER ECONOMIC LOSS;
+OR ANY SPECIAL, INCIDENTAL, INDIRECT, CONSEQUENTIAL, PUNITIVE OR
+EXEMPLARY DAMAGES ARISING OUT OF OR IN CONNECTION WITH THIS LICENCE,
+THE SOFTWARE OR THE USE OF THE SOFTWARE, EVEN IF NICTA HAS BEEN
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+
+If applicable legislation implies warranties or conditions, or
+imposes obligations or liability on NICTA in respect of the Software
+that cannot be wholly or partly excluded, restricted or modified,
+NICTA's liability is limited, to the full extent permitted by the
+applicable legislation, at its option, to:
+
+a. in the case of goods, any one or more of the following:
+ i. the replacement of the goods or the supply of equivalent goods;
+ ii. the repair of the goods;
+ iii. the payment of the cost of replacing the goods or of acquiring
+ equivalent goods;
+ iv. the payment of the cost of having the goods repaired; or
+b. in the case of services:
+ i. the supplying of the services again; or
+ ii. the payment of the cost of having the services supplied
+ again.
diff --git a/options/license/Python-2.0.1 b/options/license/Python-2.0.1
new file mode 100644
index 000000000000..2b90e0400c36
--- /dev/null
+++ b/options/license/Python-2.0.1
@@ -0,0 +1,207 @@
+PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
+--------------------------------------------
+
+1. This LICENSE AGREEMENT is between the Python Software Foundation
+("PSF"), and the Individual or Organization ("Licensee") accessing and
+otherwise using this software ("Python") in source or binary form and
+its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, PSF hereby
+grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
+analyze, test, perform and/or display publicly, prepare derivative works,
+distribute, and otherwise use Python alone or in any derivative version,
+provided, however, that PSF's License Agreement and PSF's notice of copyright,
+i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022 Python Software Foundation;
+All Rights Reserved" are retained in Python alone or in any derivative version
+prepared by Licensee.
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python.
+
+4. PSF is making Python available to Licensee on an "AS IS"
+basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. Nothing in this License Agreement shall be deemed to create any
+relationship of agency, partnership, or joint venture between PSF and
+Licensee. This License Agreement does not grant permission to use PSF
+trademarks or trade name in a trademark sense to endorse or promote
+products or services of Licensee, or any third party.
+
+8. By copying, installing or otherwise using Python, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0
+-------------------------------------------
+
+BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1
+
+1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an
+office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the
+Individual or Organization ("Licensee") accessing and otherwise using
+this software in source or binary form and its associated
+documentation ("the Software").
+
+2. Subject to the terms and conditions of this BeOpen Python License
+Agreement, BeOpen hereby grants Licensee a non-exclusive,
+royalty-free, world-wide license to reproduce, analyze, test, perform
+and/or display publicly, prepare derivative works, distribute, and
+otherwise use the Software alone or in any derivative version,
+provided, however, that the BeOpen Python License is retained in the
+Software, alone or in any derivative version prepared by Licensee.
+
+3. BeOpen is making the Software available to Licensee on an "AS IS"
+basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE
+SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS
+AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY
+DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+5. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+6. This License Agreement shall be governed by and interpreted in all
+respects by the law of the State of California, excluding conflict of
+law provisions. Nothing in this License Agreement shall be deemed to
+create any relationship of agency, partnership, or joint venture
+between BeOpen and Licensee. This License Agreement does not grant
+permission to use BeOpen trademarks or trade names in a trademark
+sense to endorse or promote products or services of Licensee, or any
+third party. As an exception, the "BeOpen Python" logos available at
+http://www.pythonlabs.com/logos.html may be used according to the
+permissions granted on that web page.
+
+7. By copying, installing or otherwise using the software, Licensee
+agrees to be bound by the terms and conditions of this License
+Agreement.
+
+
+CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1
+---------------------------------------
+
+1. This LICENSE AGREEMENT is between the Corporation for National
+Research Initiatives, having an office at 1895 Preston White Drive,
+Reston, VA 20191 ("CNRI"), and the Individual or Organization
+("Licensee") accessing and otherwise using Python 1.6.1 software in
+source or binary form and its associated documentation.
+
+2. Subject to the terms and conditions of this License Agreement, CNRI
+hereby grants Licensee a nonexclusive, royalty-free, world-wide
+license to reproduce, analyze, test, perform and/or display publicly,
+prepare derivative works, distribute, and otherwise use Python 1.6.1
+alone or in any derivative version, provided, however, that CNRI's
+License Agreement and CNRI's notice of copyright, i.e., "Copyright (c)
+1995-2001 Corporation for National Research Initiatives; All Rights
+Reserved" are retained in Python 1.6.1 alone or in any derivative
+version prepared by Licensee. Alternately, in lieu of CNRI's License
+Agreement, Licensee may substitute the following text (omitting the
+quotes): "Python 1.6.1 is made available subject to the terms and
+conditions in CNRI's License Agreement. This Agreement together with
+Python 1.6.1 may be located on the internet using the following
+unique, persistent identifier (known as a handle): 1895.22/1013. This
+Agreement may also be obtained from a proxy server on the internet
+using the following URL: http://hdl.handle.net/1895.22/1013".
+
+3. In the event Licensee prepares a derivative work that is based on
+or incorporates Python 1.6.1 or any part thereof, and wants to make
+the derivative work available to others as provided herein, then
+Licensee hereby agrees to include in any such work a brief summary of
+the changes made to Python 1.6.1.
+
+4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS"
+basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
+IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND
+DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
+FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT
+INFRINGE ANY THIRD PARTY RIGHTS.
+
+5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
+1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
+A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1,
+OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
+
+6. This License Agreement will automatically terminate upon a material
+breach of its terms and conditions.
+
+7. This License Agreement shall be governed by the federal
+intellectual property law of the United States, including without
+limitation the federal copyright law, and, to the extent such
+U.S. federal law does not apply, by the law of the Commonwealth of
+Virginia, excluding Virginia's conflict of law provisions.
+Notwithstanding the foregoing, with regard to derivative works based
+on Python 1.6.1 that incorporate non-separable material that was
+previously distributed under the GNU General Public License (GPL), the
+law of the Commonwealth of Virginia shall govern this License
+Agreement only as to issues arising under or with respect to
+Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this
+License Agreement shall be deemed to create any relationship of
+agency, partnership, or joint venture between CNRI and Licensee. This
+License Agreement does not grant permission to use CNRI trademarks or
+trade name in a trademark sense to endorse or promote products or
+services of Licensee, or any third party.
+
+8. By clicking on the "ACCEPT" button where indicated, or by copying,
+installing or otherwise using Python 1.6.1, Licensee agrees to be
+bound by the terms and conditions of this License Agreement.
+
+ ACCEPT
+
+
+CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2
+--------------------------------------------------
+
+Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam,
+The Netherlands. All rights reserved.
+
+Permission to use, copy, modify, and distribute this software and its
+documentation for any purpose and without fee is hereby granted,
+provided that the above copyright notice appear in all copies and that
+both that copyright notice and this permission notice appear in
+supporting documentation, and that the name of Stichting Mathematisch
+Centrum or CWI not be used in advertising or publicity pertaining to
+distribution of the software without specific, written prior
+permission.
+
+STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
+THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
+FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
+OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+ZERO-CLAUSE BSD LICENSE FOR CODE IN THE PYTHON DOCUMENTATION
+----------------------------------------------------------------------
+
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted.
+
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
+REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
+INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
+LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
+OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+PERFORMANCE OF THIS SOFTWARE.
diff --git a/options/license/mpi-permissive b/options/license/mpi-permissive
new file mode 100644
index 000000000000..2abcbe3ab0c6
--- /dev/null
+++ b/options/license/mpi-permissive
@@ -0,0 +1,15 @@
+* Copyright (C) 2000-2004 by Etnus, LLC
+ *
+ * Permission is hereby granted to use, reproduce, prepare derivative
+ * works, and to redistribute to others.
+ *
+ * DISCLAIMER
+ *
+ * Neither Etnus, nor any of their employees, makes any warranty
+ * express or implied, or assumes any legal liability or
+ * responsibility for the accuracy, completeness, or usefulness of any
+ * information, apparatus, product, or process disclosed, or
+ * represents that its use would not infringe privately owned rights.
+ *
+ * This code was written by
+ * James Cownie: Etnus, LLC.
diff --git a/options/license/mpich2 b/options/license/mpich2
index 5c32b0ec1d60..1fa4acbc6293 100644
--- a/options/license/mpich2
+++ b/options/license/mpich2
@@ -3,11 +3,17 @@ COPYRIGHT
The following is a notice of limited availability of the code, and disclaimer which must be included in the prologue of the code and in all source listings of the code.
Copyright Notice
-+ 2002 University of Chicago
+1998--2020, Argonne National Laboratory
Permission is hereby granted to use, reproduce, prepare derivative works, and to redistribute to others. This software was authored by:
-Argonne National Laboratory Group W. Gropp: (630) 252-4318; FAX: (630) 252-5986; e-mail: gropp@mcs.anl.gov E. Lusk: (630) 252-7852; FAX: (630) 252-5986; e-mail: lusk@mcs.anl.gov Mathematics and Computer Science Division Argonne National Laboratory, Argonne IL 60439
+Mathematics and Computer Science Division
+Argonne National Laboratory, Argonne IL 60439
+
+(and)
+
+Department of Computer Science
+University of Illinois at Urbana-Champaign
GOVERNMENT LICENSE
diff --git a/options/locale/locale_bg-BG.ini b/options/locale/locale_bg-BG.ini
index c6faee5cf605..497aab66c73a 100644
--- a/options/locale/locale_bg-BG.ini
+++ b/options/locale/locale_bg-BG.ini
@@ -8,7 +8,6 @@ sign_out=Изход
sign_up=Регистриране
link_account=Свържи профил
register=Регистрация
-website=Уебсайт
version=Версия
powered_by=С подкрепата на %s
page=Страница
@@ -129,7 +128,6 @@ log_root_path_helper=Директория, в която да се съхран
optional_title=Опционални настройки
email_title=Имейл настройки
-smtp_host=SMTP сървър
smtp_from=Изпрати имейл като
smtp_from_helper=E-mail адрес, който да се използва от Gitea. Въведете само E-mail адреса или име и E-mail във формат "Name ".
mailer_user=SMTP потребител
@@ -1151,9 +1149,7 @@ config.queue_length=Дължина на опашка
config.deliver_timeout=Време за отказ при изпращане
config.mailer_enabled=Активен
-config.mailer_disable_helo=Изключи HELO
config.mailer_name=Име
-config.mailer_host=Сървър
config.mailer_user=Потребител
config.oauth_config=OAuth конфигурация
diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini
index 2b7c18ca12bc..2b3ddeace389 100644
--- a/options/locale/locale_cs-CZ.ini
+++ b/options/locale/locale_cs-CZ.ini
@@ -8,7 +8,6 @@ sign_out=Odhlásit se
sign_up=Registrovat se
link_account=Propojit účet
register=Registrovat se
-website=Webové stránky
version=Verze
powered_by=Běží na %s
page=Strana
@@ -176,7 +175,6 @@ log_root_path_helper=Soubory protokolu budou zapsány do tohoto adresáře.
optional_title=Dodatečná nastavení
email_title=Nastavení e-mailu
-smtp_host=Server SMTP
smtp_from=Odeslat e-mail jako
smtp_from_helper=E-mailová adresa, kterou bude Gitea používat. Zadejte běžnou e-mailovou adresu, nebo použijte formát "Jméno".
mailer_user=Uživatelské jméno SMTP
@@ -994,8 +992,6 @@ file_view_rendered=Zobrazit vykreslené
file_view_raw=Zobrazit v surovém stavu
file_permalink=Trvalý odkaz
file_too_large=Soubor je příliš velký pro zobrazení.
-bidi_bad_header=`Tento soubor obsahuje neočekávané obousměrné znaky Unicode!`
-line_unicode=`Tento řádek má skryté unicode znaky`
file_copy_permalink=Kopírovat trvalý odkaz
video_not_supported_in_browser=Váš prohlížeč nepodporuje značku pro HTML5 video.
@@ -2661,11 +2657,8 @@ config.queue_length=Délka fronty
config.deliver_timeout=Časový limit doručení
config.skip_tls_verify=Přeskočit verifikaci TLS
-config.mailer_config=Konfigurace služby SMTP
config.mailer_enabled=Zapnutý
-config.mailer_disable_helo=Zakázat HELO
config.mailer_name=Název
-config.mailer_host=Server
config.mailer_user=Uživatel
config.mailer_use_sendmail=Použít Sendmail
config.mailer_sendmail_path=Cesta k Sendmail
diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini
index b4e59e504a46..84630dbc3485 100644
--- a/options/locale/locale_de-DE.ini
+++ b/options/locale/locale_de-DE.ini
@@ -9,7 +9,6 @@ sign_out=Abmelden
sign_up=Registrieren
link_account=Account verbinden
register=Registrieren
-website=Webseite
version=Version
powered_by=Powered by %s
page=Seite
@@ -179,7 +178,6 @@ log_root_path_helper=Log-Dateien werden in diesem Verzeichnis gespeichert.
optional_title=Optionale Einstellungen
email_title=E-Mail-Einstellungen
-smtp_host=SMTP-Server
smtp_from=E-Mail senden als
smtp_from_helper=E-Mail-Adresse, die von Gitea genutzt werden soll. Bitte gib die E-Mail-Adresse im Format „"Name" “ ein.
mailer_user=SMTP-Benutzername
@@ -1033,13 +1031,7 @@ file_view_rendered=Ansicht rendern
file_view_raw=Originalformat anzeigen
file_permalink=Permalink
file_too_large=Die Datei ist zu groß zum Anzeigen.
-bidi_bad_header=`Diese Datei enthält unerwartete Bidirektionale Unicode-Zeichen!`
-bidi_bad_description=`Diese Datei enthält unerwartete Bidirektionale Unicode-Zeichen, die anders verarbeitet werden können als nachstehend angezeigt. Wenn dein Anwendungsfall absichtlich und legitim ist, kannst du diese Warnung ignorieren. Benutze den "Escape" Button, um versteckte Zeichen anzuzeigen.`
-bidi_bad_description_escaped=`Diese Datei enthält unerwartete Unicode-Zeichen. Versteckte Unicode-Zeichen werden unten escaped. Benutze den "Unescapen" Button, um zu sehen, wie sie ansonsten aussehen.`
-unicode_header=`Diese Datei enthält versteckte Unicode-Zeichen!`
-unicode_description=`Diese Datei enthält versteckte Unicode-Zeichen, die anders verarbeitet werden können als unten angezeigt. Wenn dein Anwendungsfall absichtlich und legitim ist, kannst du diese Warnung ignorieren. Benutze den Escape Button, um versteckte Zeichen anzuzeigen.`
-unicode_description_escaped=`Diese Datei enthält versteckte Unicode-Zeichen. Versteckte Unicode-Zeichen werden unten escaped. Benutze den "Unescapen" Button, um zu sehen, wie sie ansonsten aussehen.`
-line_unicode=`Diese Zeile hat versteckte Unicode-Zeichen`
+ambiguous_character=`%[1]c [U+%04[1]X] kann mit %[2]c [U+%04[2]X] verwechselt werden`
escape_control_characters=Escapen
unescape_control_characters=Unescapen
@@ -1060,6 +1052,7 @@ normal_view=Normale Ansicht
line=zeile
lines=Zeilen
+editor.add_file=Datei hinzufügen
editor.new_file=Neue Datei
editor.upload_file=Datei hochladen
editor.edit_file=Datei bearbeiten
@@ -1265,6 +1258,8 @@ issues.filter_milestone=Meilenstein
issues.filter_milestone_no_select=Alle Meilensteine
issues.filter_assignee=Zuständig
issues.filter_assginee_no_select=Alle Zuständigen
+issues.filter_poster=Autor
+issues.filter_poster_no_select=Alle Autoren
issues.filter_type=Typ
issues.filter_type.all_issues=Alle Issues
issues.filter_type.assigned_to_you=Dir zugewiesen
@@ -2790,11 +2785,10 @@ config.queue_length=Warteschlangenlänge
config.deliver_timeout=Zeitlimit für Zustellung
config.skip_tls_verify=TLS-Verifikation überspringen
-config.mailer_config=SMTP-Mailer-Konfiguration
config.mailer_enabled=Aktiviert
-config.mailer_disable_helo=HELO deaktivieren
+config.mailer_enable_helo=HELO aktivieren
config.mailer_name=Name
-config.mailer_host=Host
+config.mailer_protocol=Protokoll
config.mailer_user=Benutzer
config.mailer_use_sendmail=Sendmail benutzen
config.mailer_sendmail_path=Sendmail-Pfad
@@ -3101,6 +3095,7 @@ npm.dependencies.development=Entwicklungsabhängigkeiten
npm.dependencies.peer=Peer Abhängigkeiten
npm.dependencies.optional=Optionale Abhängigkeiten
npm.details.tag=Tag
+pub.install=Um das Paket mit Dart zu installieren, führe den folgenden Befehl aus:
pypi.requires=Erfordert Python
pypi.install=Nutze folgenden Befehl, um das Paket mit pip zu installieren:
pypi.documentation=Weitere Informationen zur PyPI-Paketverwaltung findest du in der Dokumentation .
diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini
index c123bd6d2661..e06a3e539258 100644
--- a/options/locale/locale_el-GR.ini
+++ b/options/locale/locale_el-GR.ini
@@ -9,7 +9,6 @@ sign_out=Έξοδος
sign_up=Εγγραφή
link_account=Σύνδεση λογαριασμού
register=Εγγραφή
-website=Ιστοσελίδα
version=Έκδοση
powered_by=Με τη δύναμη του %s
page=Σελίδα
@@ -179,7 +178,6 @@ log_root_path_helper=Τα αρχεία καταγραφής θα γράφοντ
optional_title=Προαιρετικές Ρυθμίσεις
email_title=Ρυθμίσεις Email
-smtp_host=Διακομιστής SMTP
smtp_from=Αποστολή Email Ως
smtp_from_helper=Η διεύθυνση email που θα χρησιμοποιεί το Gitea. Εισάγετε μια απλή διεύθυνση ηλεκτρονικού ταχυδρομείου ή χρησιμοποιήστε τη μορφή "Όνομα" .
mailer_user=Όνομα Χρήστη SMTP
@@ -1034,13 +1032,6 @@ file_view_rendered=Προβολή Απόδοσης
file_view_raw=Προβολή Ακατέργαστου
file_permalink=Permalink
file_too_large=Το αρχείο είναι πολύ μεγάλο για να εμφανιστεί.
-bidi_bad_header=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Unicode!`
-bidi_bad_description=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Bidirectional Unicode που ίσως να επεξεργάζονται διαφορετικά από ότι εμφανίζεται παρακάτω. Αν η χρήση αυτή είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να αποκαλύψετε κρυμμένους χαρακτήρες.`
-bidi_bad_description_escaped=`Αυτό το αρχείο περιέχει μη αναμενόμενους χαρακτήρες Bidirectional Unicode. Οι κρυμμένοι χαρακτήρες unicode εμφανίζονται κωδικοποιημένοι παρακάτω. Χρησιμοποιήστε το κουμπί Unescape για να δείτε πώς αποδίδονται.`
-unicode_header=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode!`
-unicode_description=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode που μπορεί να επεξεργάζονται διαφορετικά από όπως εμφανίζονται παρακάτω. Αν η χρήση είναι σκόπιμη και νόμιμη, μπορείτε να αγνοήσετε με ασφάλεια αυτή την προειδοποίηση. Χρησιμοποιήστε το κουμπί Escape για να αποκαλύψετε τους κρυφούς χαρακτήρες.`
-unicode_description_escaped=`Αυτό το αρχείο περιέχει κρυφούς χαρακτήρες Unicode. Οι κρυφοί χαρακτήρες unicode εμφανίζονται κωδικοποιημένοι παρακάτω. Χρησιμοποιήστε το κουμπί Unescape για να δείτε πώς αποδίδονται.`
-line_unicode=`Αυτή η γραμμή έχει κρυφούς χαρακτήρες unicode`
escape_control_characters=Escape
unescape_control_characters=Unescape
@@ -2794,11 +2785,8 @@ config.queue_length=Μέγεθος Ουράς
config.deliver_timeout=Χρονικό Όριο Παράδοσης
config.skip_tls_verify=Παράλειψη Επαλήθευσης TLS
-config.mailer_config=Ρυθμίσεις SMTP Mailer
config.mailer_enabled=Ενεργοποιημένο
-config.mailer_disable_helo=Απενεργοποίηση HELO
config.mailer_name=Όνομα
-config.mailer_host=Διακομιστής
config.mailer_user=Χρήστης
config.mailer_use_sendmail=Χρήση Sendmail
config.mailer_sendmail_path=Διαδρομή Sendmail
diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini
index a774bf92fff4..0e309279d29b 100644
--- a/options/locale/locale_en-US.ini
+++ b/options/locale/locale_en-US.ini
@@ -9,7 +9,6 @@ sign_out = Sign Out
sign_up = Register
link_account = Link Account
register = Register
-website = Website
version = Version
powered_by = Powered by %s
page = Page
@@ -1036,13 +1035,13 @@ file_view_rendered = View Rendered
file_view_raw = View Raw
file_permalink = Permalink
file_too_large = The file is too large to be shown.
-bidi_bad_header = `This file contains unexpected Bidirectional Unicode characters!`
-bidi_bad_description = `This file contains unexpected Bidirectional Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.`
-bidi_bad_description_escaped = `This file contains unexpected Bidirectional Unicode characters. Hidden unicode characters are escaped below. Use the Unescape button to show how they render.`
-unicode_header = `This file contains hidden Unicode characters!`
-unicode_description = `This file contains hidden Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.`
-unicode_description_escaped = `This file contains hidden Unicode characters. Hidden unicode characters are escaped below. Use the Unescape button to show how they render.`
-line_unicode = `This line has hidden unicode characters`
+invisible_runes_header = `This file contains invisible Unicode characters!`
+invisible_runes_description = `This file contains invisible Unicode characters that may be processed differently from what appears below. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to reveal hidden characters.`
+ambiguous_runes_header = `This file contains ambiguous Unicode characters!`
+ambiguous_runes_description = `This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.`
+invisible_runes_line = `This line has invisible unicode characters`
+ambiguous_runes_line = `This line has ambiguous unicode characters`
+ambiguous_character = `%[1]c [U+%04[1]X] is confusable with %[2]c [U+%04[2]X]`
escape_control_characters = Escape
unescape_control_characters = Unescape
@@ -1063,6 +1062,7 @@ normal_view = Normal View
line = line
lines = lines
+editor.add_file = Add File
editor.new_file = New File
editor.upload_file = Upload File
editor.edit_file = Edit File
@@ -1268,6 +1268,8 @@ issues.filter_milestone = Milestone
issues.filter_milestone_no_select = All milestones
issues.filter_assignee = Assignee
issues.filter_assginee_no_select = All assignees
+issues.filter_poster = Author
+issues.filter_poster_no_select = All authors
issues.filter_type = Type
issues.filter_type.all_issues = All issues
issues.filter_type.assigned_to_you = Assigned to you
@@ -2796,16 +2798,19 @@ config.queue_length = Queue Length
config.deliver_timeout = Deliver Timeout
config.skip_tls_verify = Skip TLS Verification
-config.mailer_config = SMTP Mailer Configuration
+config.mailer_config = Mailer Configuration
config.mailer_enabled = Enabled
-config.mailer_disable_helo = Disable HELO
+config.mailer_enable_helo = Enable HELO
config.mailer_name = Name
-config.mailer_host = Host
+config.mailer_protocol = Protocol
+config.mailer_smtp_addr = SMTP Addr
+config.mailer_smtp_port = SMTP Port
config.mailer_user = User
config.mailer_use_sendmail = Use Sendmail
config.mailer_sendmail_path = Sendmail Path
config.mailer_sendmail_args = Extra Arguments to Sendmail
config.mailer_sendmail_timeout = Sendmail Timeout
+config.mailer_use_dummy = Dummy
config.test_email_placeholder = Email (e.g. test@example.com)
config.send_test_mail = Send Testing Email
config.test_mail_failed = Failed to send a testing email to '%s': %v
@@ -2890,6 +2895,7 @@ monitor.queue.nopool.title = No Worker Pool
monitor.queue.nopool.desc = This queue wraps other queues and does not itself have a worker pool.
monitor.queue.wrapped.desc = A wrapped queue wraps a slow starting queue, buffering queued requests in a channel. It does not have a worker pool itself.
monitor.queue.persistable-channel.desc = A persistable-channel wraps two queues, a channel queue that has its own worker pool and a level queue for persisted requests from previous shutdowns. It does not have a worker pool itself.
+monitor.queue.flush = Flush worker
monitor.queue.pool.timeout = Timeout
monitor.queue.pool.addworkers.title = Add Workers
monitor.queue.pool.addworkers.submit = Add Workers
@@ -3108,6 +3114,10 @@ npm.dependencies.development = Development Dependencies
npm.dependencies.peer = Peer Dependencies
npm.dependencies.optional = Optional Dependencies
npm.details.tag = Tag
+pub.install = To install the package using Dart, run the following command:
+pub.documentation = For more information on the Pub registry, see the documentation .
+pub.details.repository_site = Repository Site
+pub.details.documentation_site = Documentation Site
pypi.requires = Requires Python
pypi.install = To install the package using pip, run the following command:
pypi.documentation = For more information on the PyPI registry, see the documentation .
diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini
index 4507bc553b6a..ea1ce54749a7 100644
--- a/options/locale/locale_es-ES.ini
+++ b/options/locale/locale_es-ES.ini
@@ -9,7 +9,6 @@ sign_out=Cerrar sesión
sign_up=Registrarse
link_account=Vincular cuenta
register=Registro
-website=Página web
version=Versión
powered_by=Impulsado por %s
page=Página
@@ -179,7 +178,8 @@ log_root_path_helper=Archivos de registro se escribirán en este directorio.
optional_title=Configuración opcional
email_title=Configuración de Correo
-smtp_host=Servidor SMTP
+smtp_addr=Servidor SMTP
+smtp_port=Puerto SMTP
smtp_from=Enviar correos electrónicos como
smtp_from_helper=Dirección de correo electrónico que utilizará Gitea. Introduzca una dirección de correo electrónico normal o utilice el formato "Nombre" .
mailer_user=Nombre de usuario SMTP
@@ -978,7 +978,7 @@ migrate.migrating_topics=Migrando Temas
migrate.migrating_milestones=Migrando Hitos
migrate.migrating_labels=Migrando etiquetas
migrate.migrating_releases=Migrando Lanzamientos
-migrate.migrating_issues=Migrando Incidencías
+migrate.migrating_issues=Migrando incidencias
migrate.migrating_pulls=Migrando Pull Requests
mirror_from=réplica de
@@ -1035,13 +1035,13 @@ file_view_rendered=Ver procesado
file_view_raw=Ver original
file_permalink=Enlace permanente
file_too_large=El archivo es demasiado grande para ser mostrado.
-bidi_bad_header=`¡Este archivo contiene caracteres Unicode bidireccional inesperados!`
-bidi_bad_description=`Este archivo contiene caracteres Bidirectional Unicode inesperados que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.`
-bidi_bad_description_escaped=`Este archivo contiene caracteres Unicode bidireccionales inesperados. Los caracteres unicode ocultos se escapan debajo. Utilice el botón Unescape para mostrar cómo se renderizan.`
-unicode_header=`¡Este archivo contiene caracteres Unicode ocultos!`
-unicode_description=`Este archivo contiene caracteres Unicode ocultos que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.`
-unicode_description_escaped=`Este archivo contiene caracteres Unicode ocultos. Los caracteres unicode ocultos se escapan debajo. Utilice el botón Unescape para mostrar cómo renderizan.`
-line_unicode=`Esta línea tiene caracteres unicode ocultos`
+invisible_runes_header=`¡Este archivo contiene caracteres Unicode invisibles!`
+invisible_runes_description=`Este archivo contiene caracteres Unicode invisibles que pueden ser procesados de forma diferente a lo que aparece a continuación. Si su caso de uso es intencional y legítimo, puede ignorar esta advertencia. Use el botón de Escape para revelar caracteres ocultos.`
+ambiguous_runes_header=`¡Este archivo contiene caracteres Unicode ambiguos!`
+ambiguous_runes_description=`Este archivo contiene caracteres Unicode ambiguos que pueden confundirse con otros en tu idioma actual. Si tu caso de uso es intencional y legítimo, puedes ignorar esta advertencia. Usa el botón de Escape para resaltar estos caracteres.`
+invisible_runes_line=`Esta línea tiene caracteres unicode invisibles`
+ambiguous_runes_line=`Esta línea tiene caracteres unicode ambiguos`
+ambiguous_character=`%[1]c [U+%04[1]X] es confusable con %[2]c [U+%04[2]X]`
escape_control_characters=Escapar
unescape_control_characters=No Escapar
@@ -1062,6 +1062,7 @@ normal_view=Vista normal
line=línea
lines=líneas
+editor.add_file=Añadir archivo
editor.new_file=Nuevo Archivo
editor.upload_file=Subir archivo
editor.edit_file=Editar Archivo
@@ -1267,6 +1268,8 @@ issues.filter_milestone=Milestone
issues.filter_milestone_no_select=Todos los hitos
issues.filter_assignee=Asignada a
issues.filter_assginee_no_select=Todos los asignados
+issues.filter_poster=Autor
+issues.filter_poster_no_select=Todos los autores
issues.filter_type=Tipo
issues.filter_type.all_issues=Todas las incidencias
issues.filter_type.assigned_to_you=Asignadas a ti
@@ -2797,14 +2800,17 @@ config.skip_tls_verify=Saltar verificación TLS
config.mailer_config=Configuración del servidor de correo
config.mailer_enabled=Activado
-config.mailer_disable_helo=Desactivar HELO
+config.mailer_enable_helo=Habilitar HELO
config.mailer_name=Nombre
-config.mailer_host=Servidor
+config.mailer_protocol=Protocolo
+config.mailer_smtp_addr=Dirección SMTP
+config.mailer_smtp_port=Puerto SMTP
config.mailer_user=Usuario
config.mailer_use_sendmail=Usar Sendmail
config.mailer_sendmail_path=Ruta de Sendmail
config.mailer_sendmail_args=Argumentos adicionales por Sendmail
config.mailer_sendmail_timeout=Tiempo de espera de Sendmail
+config.mailer_use_dummy=Dummy
config.test_email_placeholder=Correo electrónico (ej. test@ejemplo.com)
config.send_test_mail=Enviar prueba de correo
config.test_mail_failed=Fallo al enviar correo electrónico de prueba a '%s': %v
@@ -2889,6 +2895,7 @@ monitor.queue.nopool.title=No existe un grupo de trabajadores
monitor.queue.nopool.desc=Esta cola envuelve otras colas y no tiene grupos de trabajadores.
monitor.queue.wrapped.desc=Una cola de tipo envuelto envuelve una cola de inicio lenta, búfer de peticiones en un canal. No tiene grupos de trabajadores en si misma.
monitor.queue.persistable-channel.desc=Una cola de tipo canal persistente envuelve dos colas, una cola de canales que tiene sus propios grupos de trabajadores y una cola de niveles para peticiones persistentes de apagones anteriores. No tiene grupos de trabajadores en sí misma.
+monitor.queue.flush=Vaciar trabajador
monitor.queue.pool.timeout=Tiempo de espera
monitor.queue.pool.addworkers.title=Añadir trabajadores
monitor.queue.pool.addworkers.submit=Añadir trabajadores
@@ -3107,6 +3114,10 @@ npm.dependencies.development=Dependencias de desarrollo
npm.dependencies.peer=Dependencias de pares
npm.dependencies.optional=Dependencias opcionales
npm.details.tag=Etiqueta
+pub.install=Para instalar el paquete usando Dart, ejecute el siguiente comando:
+pub.documentation=Para obtener más información sobre el registro de Pub, consulte la documentación .
+pub.details.repository_site=Sitio del repositorio
+pub.details.documentation_site=Sitio de documentación
pypi.requires=Requiere Python
pypi.install=Para instalar el paquete usando pip, ejecute el siguiente comando:
pypi.documentation=Para obtener más información sobre el registro PyPI, consulte la documentación .
diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini
index 9999425f157f..d60b6dceea44 100644
--- a/options/locale/locale_fa-IR.ini
+++ b/options/locale/locale_fa-IR.ini
@@ -8,7 +8,6 @@ sign_out=خروج
sign_up=ثبت نام
link_account=پیوند به حساب
register=ثبت نام
-website=وبسایت
version=نسخه
powered_by=قدرت از %s
page=صفحه
@@ -158,7 +157,6 @@ log_root_path_helper=فایلهای گزارش روی این مسیر ذخی
optional_title=تنظیمات اختیاری
email_title=تنظیمات ایمیل
-smtp_host=میزبان SMTP
smtp_from=ارسال ایمیل به عنوان
smtp_from_helper=آدرس ایمیلی که گیتی استفاده میکند. یک ایمیل وارد کنید یا به "Name" شکل استفاده کنید.
mailer_user=نام کاربری SMTP
@@ -2576,11 +2574,8 @@ config.queue_length=طول صف
config.deliver_timeout=مهلت تحویل
config.skip_tls_verify=صرف نظر از اعتبارسنجی TLS
-config.mailer_config=پیکربندی سامانه ایمیلی SMTP
config.mailer_enabled=فعال شده
-config.mailer_disable_helo=غیر فعال کردن HELO
config.mailer_name=نام
-config.mailer_host=میزبان
config.mailer_user=کاربر
config.mailer_use_sendmail=استفاده از ارسال رایانامه (ایمیل) مستقیم
config.mailer_sendmail_path=مسیر ارسال ایمیل مستقیم
diff --git a/options/locale/locale_fi-FI.ini b/options/locale/locale_fi-FI.ini
index 2699598ed9b2..7c0cc310973c 100644
--- a/options/locale/locale_fi-FI.ini
+++ b/options/locale/locale_fi-FI.ini
@@ -2,13 +2,13 @@ home=Etusivu
dashboard=Kojelauta
explore=Tutki
help=Apua
+logo=Logo
sign_in=Kirjaudu sisään
sign_in_with=Kirjaudu sisään tunnuksilla
sign_out=Kirjaudu ulos
sign_up=Rekisteröidy
link_account=Yhdistä tili
register=Rekisteröidy
-website=Nettisivut
version=Versio
powered_by=Voimanlähteenä %s
page=Sivu
@@ -21,16 +21,28 @@ signed_in_as=Kirjautuneena käyttäjänä
enable_javascript=Tämä sivusto toimii paremmin JavaScriptillä.
toc=Sisällysluettelo
licenses=Lisenssit
+return_to_gitea=Palaa Giteaan
username=Käyttäjätunnus
email=Sähköpostiosoite
password=Salasana
+access_token=Pääsymerkki
re_type=Kirjoita salasana uudelleen
captcha=CAPTCHA
twofa=Kaksivaiheinen todennus
twofa_scratch=Kaksivaiheinen kertakäyttöinen koodi
passcode=Tunnuskoodi
+webauthn_insert_key=Aseta turva-avaimesi
+webauthn_press_button=Paina turva-avaimesi painiketta…
+webauthn_error=Turva-avainta ei voitu lukea.
+webauthn_unsupported_browser=Selaimesi ei tällä hetkellä tue WebAuthnia.
+webauthn_error_insecure=WebAuthn tukee vain suojattuja yhteyksiä. Testaukseen HTTP:n yli, voit käyttää osoitetta "localhost" tai "127.0.0.1"
+webauthn_error_unable_to_process=Palvelin ei pystynyt toteuttamaan kutsua.
+webauthn_error_duplicated=Turva-avainta ei ole sallittu tässä pyynnössä. Varmista, ettei avainta ole jo rekisteröity.
+webauthn_error_empty=Sinun täytyy asettaa nimi tälle avaimelle.
+webauthn_error_timeout=Aikakatkaisu saavutettu ennenkuin avaintasi on voitu lukea. Lataa tämä sivu uudelleen ja yritä uudelleen.
+webauthn_reload=Päivitä
repository=Repo
organization=Organisaatio
@@ -40,6 +52,7 @@ new_migrate=Uusi migraatio
new_mirror=Uusi peilaus
new_fork=Uusi repositorio
new_org=Uusi organisaatio
+new_project=Uusi projekti
manage_org=Ylläpidä organisaatioita
admin_panel=Sivuston ylläpito
account_settings=Tilin asetukset
@@ -59,28 +72,47 @@ pull_requests=Pull requestit
issues=Ongelmat
milestones=Merkkipaalut
+ok=OK
cancel=Peruuta
save=Tallenna
add=Lisää
add_all=Lisää kaikki
remove=Poista
remove_all=Poista kaikki
+edit=Muokkaa
+copy=Kopioi
+copy_url=Kopioi osoite
+copy_branch=Kopioi haaran nimi
+copy_success=Kopioitu!
+copy_error=Kopiointi epäonnistui
write=Kirjoita
preview=Esikatselu
loading=Ladataan…
+step1=Vaihe 1:
+step2=Vaihe 2:
+error=Virhe
error404=Sivu, jota yrität nähdä, joko ei löydy tai et ole oikeutettu katsomaan sitä.
+never=Ei koskaan
+rss_feed=RSS-syöte
[error]
+occurred=Virhe tapahtui
+report_message=Jos olet varma, että tämä on ongelma Giteassa, etsi ongelmaa GitHubista tai avaa uusi ongelma tarvittaessa.
+missing_csrf=Virheellinen pyyntö: CSRF-tunnusta ei ole olemassa
+invalid_csrf=Virheellinen pyyntö: Virheellinen CSRF-tunniste
+not_found=Kohdetta ei löytynyt.
+network_error=Verkkovirhe
[startpage]
app_desc=Kivuton, itsehostattu Git-palvelu
install=Helppo asentaa
+install_desc=Yksinkertaisesti aja binääri alustallasi, toimita se Dockerilla , tai saa se pakettina .
platform=Alustariippumaton
platform_desc=Gitea käy missä tahansa alustassa, johon Go kykenee kääntämään. Windows, macOS, Linux, ARM, jne. Valitse omasi!
lightweight=Kevyt
@@ -92,6 +124,7 @@ license_desc=Mene osoitteeseen ohjeet ennen minkään asetuksen muuttamista.
+require_db_desc=Gitea tarvitsee toimiakseen MySQL, PostgreSQL, MSSQL, SQLite3 tai TiDB (MySQL protokolla) tietokannan.
db_title=Tietokanta asetukset
db_type=Tietokanta tyyppi
host=Isäntä
@@ -99,10 +132,16 @@ user=Käyttäjätunnus
password=Salasana
db_name=Tietokannan nimi
db_helper=Huomautus MySQL-käyttäjille: käytä InnoDB-tallennusmoottoria, ja jos käytät "utf8mb4" merkistöä, InnoDB-version on oltava yli 5.6.
+db_schema=Skeema
ssl_mode=SSL
charset=Merkistö
path=Polku
sqlite_helper=SQLite3-tietokannan tiedostopolku. Syötä absoluuttinen polku, jos ajat Giteaa palveluna.
+reinstall_error=Yrität asentaa olemassa olevaan Gitea tietokantaan
+reinstall_confirm_message=Asentaminen uudelleen olemassa olevalla Gitea-tietokannalla voi aiheuttaa useita ongelmia. Useimmissa tapauksissa sinun pitäisi käyttää olemassa olevia "app.ini" asetuksia Gitean käyttöön. Jos tiedät mitä teet, vahvista seuraavat seikat:
+reinstall_confirm_check_1=Tiedot, jotka on salattu SECRET_KEY:llä app.ini:ssä saatetaan menettää: käyttäjät eivät ehkä voi kirjautua sisään 2FA/OTP:lla ja peilit eivät välttämättä toimi oikein. Ruksaamalla tämän vahvistat, että nykyinen app.ini -tiedosto sisältää oikean SECRET_KEY:n.
+reinstall_confirm_check_2=Repot ja asetukset saattaa olla tarpeen uudelleensynkronoida. Valitsemalla tämän vahvistat, että uudelleensynkronoit repojen koukut ja authorized_keys -tiedoston manuaalisesti. Varmistat, että repon ja peilin asetukset ovat oikeat.
+reinstall_confirm_check_3=Vahvistat, että olet täysin varma siitä, että tämä Gitea toimii oikealla app.ini sijainnilla ja että olet varma, että sinun täytyy asentaa uudelleen. Vahvistat, että tunnustat edellä mainitut riskit.
err_empty_db_path=SQLite3-tietokannan polku ei voi olla tyhjä.
no_admin_and_disable_registration=Et voi kytkeä rekisteröintiä pois luomatta sitä ennen ylläpitotiliä.
err_empty_admin_password=Ylläpitäjän salasana ei voi olla tyhjä.
@@ -119,6 +158,7 @@ lfs_path=Git LFS -juuripolku
lfs_path_helper=Git LFS:n ylläpitämät tiedostot tullaan tallentamaan tähän hakemistoon. Jätä tyhjäksi kytkeäksesi toiminnon pois.
run_user=Aja käyttäjänä
run_user_helper=Anna käyttäjätunnus, jona Giteaa ajetaan. Käyttäjällä on oltava oikeudet repositorioiden juuripolkuun.
+domain=Palvelimen verkkotunnus
ssh_port=SSH-palvelimen portti
ssh_port_helper=Porttinumero, jossa SSH-palvelimesi kuuntelee. Jätä tyhjäksi kytkeäksesi pois.
http_port=Gitean HTTP-kuunteluportti
@@ -130,7 +170,6 @@ log_root_path_helper=Lokitiedostot kirjoitetaan tähän kansioon.
optional_title=Valinnaiset asetukset
email_title=Sähköpostiasetukset
-smtp_host=SMTP isäntä
smtp_from=Lähetä sähköpostit osoitteella
smtp_from_helper=Sähköpostiosoite, jota Gitea käyttää. Kirjoita osoite ”nimi” -muodossa.
mailer_user=SMTP-käyttäjätunnus
@@ -151,6 +190,7 @@ openid_signin=Ota OpenID kirjautuminen käyttöön
openid_signin_popup=Ota käyttöön kirjautuminen OpenID:n kautta.
openid_signup=Ota käyttöön OpenID itse-rekisteröinti
openid_signup_popup=Ota käyttöön OpenID-pohjainen käyttäjän itse-rekisteröinti.
+enable_captcha=Ota käyttöön CAPTCHA rekisteröityessä
enable_captcha_popup=Pakollinen captcha käyttäjän itse rekisteröityessä.
require_sign_in_view=Vaadi sisäänkirjautuminen sivujen näkemiseksi
require_sign_in_view_popup=Rajoita pääsy vain kirjautuneille käyttäjille. Vierailijat näkevät vain 'kirjaudu sisään' ja rekisteröidy -sivut.
@@ -165,22 +205,42 @@ test_git_failed=Epäonnistui testata 'git' komentoa: %v
sqlite3_not_available=Tämä Gitea versio ei tue SQLite3. Lataa virallinen binääriversio kohteesta %s (ei 'gobuild' versio).
invalid_db_setting=Tietokanta-asetukset ovat väärin: %v
invalid_repo_path=Repojen juuri polku on virheellinen: %v
+invalid_app_data_path=Sovelluksen datapolku on virheellinen: %v
+internal_token_failed=Sisäisen pääsymerkin luonti epäonnistui: %v
save_config_failed=Asetusten tallentaminen epäonnistui: %v
install_success=Tervetuloa! Kiitos kun valitsit Gitean. Pidä hauskaa!
+default_keep_email_private=Piilota sähköpostiosoitteet oletuksena
+default_enable_timetracking=Ota ajan seuranta oletusarvoisesti käyttöön
+default_enable_timetracking_popup=Ota käyttöön uusien repojen aikaseuranta oletusarvoisesti.
+no_reply_address=Piilotettu sähköpostin verkkotunnus
+no_reply_address_helper=Verkkotunnuksen nimi käyttäjille, joilla on piilotettu sähköpostiosoite. Esimerkiksi käyttäjätunnus 'joe' kirjataan Git nimellä 'joe@noreply.example.org' jos piilotettu sähköpostiosoite on asetettu 'noreply.example.org'.
+password_algorithm=Salasanan hajautusalgoritmi
+password_algorithm_helper=Aseta salasanan hajautusalgoritmi. Algoritmeillä on eri vaatimukset ja vahvuudet. `argon2`, vaikka sillä on hyvät ominaisuudet, käyttää paljon muistia ja voi olla sopimaton pienille järjestelmille.
[home]
uname_holder=Käyttäjätunnus tai sähköpostiosoite
password_holder=Salasana
switch_dashboard_context=Vaihda kojelaudan kontekstia
my_repos=Repot
+show_more_repos=Näytä lisää repoja…
collaborative_repos=Yhteistyö repot
my_orgs=Organisaationi
my_mirrors=Peilini
view_home=Näytä %s
search_repos=Etsi repo…
+filter=Muut suodattimet
+filter_by_team_repositories=Suodata tiimin repojen mukaan
+feed_of=Syöte "%s"
+show_archived=Arkistoidut
+show_both_archived_unarchived=Näytetään arkistoidut ja arkistoimattomat
+show_only_archived=Näytetään vain arkistoidut
+show_only_unarchived=Näytetään vain arkistoimattomat
show_private=Yksityinen
+show_both_private_public=Näytetään sekä julkiset että yksityiset
+show_only_private=Näytetään vain yksityiset
+show_only_public=Näytetään vain julkiset
issues.in_your_repos=Repoissasi
@@ -190,6 +250,7 @@ users=Käyttäjät
organizations=Organisaatiot
search=Hae
code=Koodi
+search.match=Osuma
repo_no_results=Vastaavia repoja ei löydy.
user_no_results=Vastaavia käyttäjiä ei löytynyt.
org_no_results=Ei löytynyt vastaavia organisaatioita.
@@ -203,6 +264,7 @@ register_helper_msg=On jo tili? Kirjaudu sisään nyt!
social_register_helper_msg=Onko sinulla jo tili? Linkitä se nyt!
disable_register_prompt=Rekisteröinti on estetty. Ota yhteys ylläpitäjääsi.
disable_register_mail=Sähköpostivahvistus rekisteröinnille on estetty.
+remember_me=Muista tämä laite
forgot_password_title=Unohtuiko salasana
forgot_password=Unohtuiko salasana?
sign_up_now=Tarvitsetko tilin? Rekisteröidy nyt.
@@ -210,6 +272,7 @@ sign_up_successful=Tilin luonti onnistui.
confirmation_mail_sent_prompt=Uusi varmistussähköposti on lähetetty osoitteeseen %s , ole hyvä ja tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi rekisteröintiprosessin valmiiksi.
must_change_password=Vaihda salasanasi
allow_password_change=Vaadi käyttäjää vaihtamaan salasanansa (suositeltava)
+reset_password_mail_sent_prompt=Varmistussähköposti on lähetetty osoitteeseen %s . Tarkista saapuneet seuraavan %s tunnin sisällä saadaksesi tilin palauttamisen valmiiksi.
active_your_account=Aktivoi tilisi
account_activated=Tili on aktivoitu
prohibit_login=Kirjautuminen estetty
@@ -218,9 +281,11 @@ resent_limit_prompt=Olet jo tilannut aktivointisähköpostin hetki sitten. Ole h
has_unconfirmed_mail=Hei %s, sinulla on varmistamaton sähköposti osoite (%s ). Jos et ole saanut varmistus sähköpostia tai tarvitset uudelleenlähetyksen, ole hyvä ja klikkaa allaolevaa painiketta.
resend_mail=Klikkaa tästä uudelleenlähettääksesi aktivointi sähköpostisi
email_not_associate=Tätä sähköpostiosoitetta ei ole liitetty mihinkään tiliin.
+send_reset_mail=Lähetä tilin palautussähköposti
reset_password=Tilin palautus
invalid_code=Vahvistusavain on virheellinen tai vanhentunut.
reset_password_helper=Palauta käyttäjätili
+reset_password_wrong_user=Olet kirjautunut sisään nimellä %s, mutta tilin palautuslinkki on tarkoitettu kohteelle %s
password_too_short=Salasanan pituus ei voi olla vähemmän kuin %d merkkiä.
non_local_account=Ei-lokaalit käyttäjät eivät voi päivittää salasanojaan Gitean web-käyttöliittymän kautta.
verify=Vahvista
@@ -232,10 +297,12 @@ twofa_scratch_token_incorrect=Kertakäyttökoodisi on virheellinen.
login_userpass=Kirjaudu sisään
login_openid=OpenID
oauth_signup_tab=Rekisteröi uusi tili
+oauth_signup_title=Viimeistele tili
oauth_signup_submit=Viimeistele tili
oauth_signin_tab=Linkitä olemassa olevaan tiliin
oauth_signin_title=Kirjaudu sisään valtuuttaaksesi linkitetyn tilin
oauth_signin_submit=Yhdistä tiliin
+oauth.signin.error.access_denied=Valtuutuspyyntö on evätty.
openid_connect_submit=Connect
openid_connect_title=Yhdistä olemassaolevaan tiliin
openid_connect_desc=Valittu OpenID-osoite on tuntematon. Liitä se uuteen tiliin täällä.
@@ -251,22 +318,38 @@ authorize_title=Valtuutatko "%s" pääsemään tilillesi?
authorization_failed=Käyttöoikeuden varmistus epäonnistui
authorization_failed_desc=Käyttöoikeuden varmistus epäonnistui virheellisen pyynnön takia. Ota yhteyttä sovelluksen ylläpitäjään, jonka olet yrittänyt valtuuttaa.
sspi_auth_failed=SSPI todennus epäonnistui
+password_pwned=Valitsemasi salasana on varastettujen salasanojen luettelossa , joka on aiemmin paljastunut julkisissa tietorikkomuksissa. Yritä uudelleen toisella salasanalla.
[mail]
+view_it_on=Näytä %s
+link_not_working_do_paste=Eikö toimi? Yritä kopioida ja liittää se selaimeesi.
+hi_user_x=Hei %s ,
activate_account=Ole hyvä ja aktivoi tilisi
activate_email=Vahvista sähköpostiosoitteesi
+activate_email.title=%s, vahvista sähköpostiosoitteesi
register_notify=Tervetuloa Giteaan
+register_notify.text_2=Voit nyt kirjautua käyttäjätunnuksella: %s.
reset_password=Palauta käyttäjätili
+reset_password.title=%s, olet pyytänyt tilisi palauttamista
register_success=Rekisteröinti onnistui
+issue.x_mentioned_you=@%s mainitsi sinut:
+issue.action.push_1=@%[1]s työnsi %[3]d commitin kohteeseen %[2]s
+issue.action.push_n=@%[1]s työnsi %[3]d committia kohteeseen %[2]s
+release.title=Otsikko: %s
+release.note=Huomautus:
+release.downloads=Lataukset:
+release.download.zip=Lähdekoodi (ZIP)
+release.download.targz=Lähdekoodi (TAR.GZ)
+repo.transfer.to_you=sinä
[modal]
@@ -287,6 +370,7 @@ AuthName=Luvan nimi
AdminEmail=Ylläpito sähköposti
NewBranchName=Uuden haaran nimi
+CommitSummary=Commitin yhteenveto
CommitMessage=Commitin viesti
CommitChoice=Commitin valinta
TreeName=Tiedostopolku
@@ -302,17 +386,24 @@ max_size_error=` täytyy sisältää enintään %s merkkiä.`
email_error=` ei ole kelvollinen sähköpostiosoite.`
include_error=` täytyy sisältää tekstiosa '%s'.`
unknown_error=Tuntematon virhe:
+captcha_incorrect=CAPTCHA koodi on virheellinen.
password_not_match=Salasanat eivät täsmää.
+lang_select_error=Valitse kieli listalta.
username_been_taken=Käyttäjätunnus on jo varattu.
+repo_name_been_taken=Repon nimi on jo käytössä.
+repository_force_private=Pakotettu yksityisyys käytössä: yksityisiä repoja ei voida muuttaa julkisiksi.
org_name_been_taken=Organisaation nimi on jo käytössä.
team_name_been_taken=Tiimin nimi on jo varattu.
email_been_used=Sähköpostiosoite on jo käytössä.
+email_invalid=Sähköpostiosoite on virheellinen.
+openid_been_used=OpenID-osoite '%s' on jo käytössä.
username_password_incorrect=Käyttäjätunnus tai salasana on virheellinen.
password_lowercase_one=Ainakin yksi pieni kirjan
password_uppercase_one=Ainakin yksi iso kirjain
password_digit_one=Ainakin yksi numero
password_special_one=Ainakin yksi erikoismerkki (välimerkki, sulut, lainausmerkit, jne.)
+enterred_invalid_org_name=Antamasi organisaation nimi on virheellinen.
enterred_invalid_password=Syöttämäsi salasana oli väärä.
user_not_exist=Käyttäjää ei ole olemassa.
team_not_exist=Tiimiä ei ole olemassa.
@@ -333,16 +424,20 @@ repositories=Repot
activity=Julkinen toiminta
followers=Seuraajat
starred=Tähdelliset repot
+projects=Projektit
following=Seurataan
follow=Seuraa
unfollow=Lopeta seuraaminen
+heatmap.loading=Ladataan lämpökarttaa…
user_bio=Elämäkerta
form.name_reserved=Käyttäjätunnus '%s' on varattu.
+form.name_chars_not_allowed=Käyttäjänimi '%s' sisältää virheellisiä merkkejä.
[settings]
profile=Profiili
account=Tili
+appearance=Ulkoasu
password=Salasana
security=Turvallisuus
avatar=Profiilikuva
@@ -356,8 +451,10 @@ twofa=Kaksivaiheinen todennus
account_link=Linkitetyt tilit
organization=Organisaatiot
uid=Käyttäjä ID
+webauthn=Turva-avaimet
public_profile=Julkinen profiili
+biography_placeholder=Kerro itsestäsi
profile_desc=Sähköpostiosoitettasi käytetään ilmoituksiin ja muihin toimintoihin.
password_username_disabled=Ei-paikalliset käyttäjät eivät voi muuttaa käyttäjätunnustaan. Ole hyvä ja ota yhteyttä sivuston ylläpitäjään saadaksesi lisätietoa.
full_name=Kokonimi
@@ -365,6 +462,9 @@ website=Nettisivut
location=Sijainti
update_theme=Päivitä teema
update_profile=Päivitä profiili
+update_language=Päivitä kieli
+update_language_not_found=Kieli '%s' ei ole käytettävissä.
+update_language_success=Kieli on päivitetty.
update_profile_success=Profiilisi on päivitetty.
change_username=Käyttäjätunnuksesi on muutettu.
change_username_prompt=Huomio: käyttäjätunnuksen muutos muuttaa myös tilisi URL:n.
@@ -372,6 +472,23 @@ continue=Jatka
cancel=Peruuta
language=Kieli
ui=Teema
+hidden_comment_types=Piilotetut kommenttityypit
+comment_type_group_reference=Viittaus
+comment_type_group_label=Tunniste
+comment_type_group_milestone=Merkkipaalu
+comment_type_group_assignee=Osoitettu henkilölle
+comment_type_group_title=Otsikko
+comment_type_group_branch=Haara
+comment_type_group_time_tracking=Ajan seuranta
+comment_type_group_deadline=Määräaika
+comment_type_group_dependency=Riippuvuus
+comment_type_group_lock=Lukituksen tila
+comment_type_group_review_request=Arviointipyyntö
+comment_type_group_pull_request_push=Lisätyt commitit
+comment_type_group_project=Projekti
+saved_successfully=Asetuksesi tallennettiin onnistuneesti.
+privacy=Yksityisyys
+keep_activity_private=Piilota toiminta profiilisivulta
lookup_avatar_by_mail=Hae profiilikuva sähköpostin perusteella
federated_avatar_lookup=Ulkopuolinen profiilikuvan haku
@@ -398,17 +515,23 @@ primary=Ensisijainen
activated=Aktivoitu
requires_activation=Vaatii aktivoinnin
primary_email=Tee ensisijainen
+activate_email=Lähetä aktivointi
+activations_pending=Odottaa aktivointia
delete_email=Poista
email_deletion=Poista sähköpostiosoite
email_deletion_desc=Sähköpostiosoite ja siihen liittyvät tiedot poistetaan tililtäsi. Kyseisen sähköpostiosoitteen sisältävät commitit pysyvät muuttumattomia. Jatketaanko?
email_deletion_success=Sähköpostiosoite on poistettu.
theme_update_success=Teemasi on päivitetty.
theme_update_error=Valittua teemaa ei löydy.
+openid_deletion=Poista OpenID-osoite
+openid_deletion_success=OpenID-osoite on poistettu.
add_new_email=Lisää uusi sähköpostiosoite
add_new_openid=Lisää uusi OpenID URI
add_email=Lisää sähköpostiosoite
add_openid=Lisää OpenID URI
add_email_success=Uusi sähköpostiosoite on lisätty.
+email_preference_set_success=Sähköpostin asetukset on asetettu onnistuneesti.
+add_openid_success=Uusi OpenID-osoite on lisätty.
keep_email_private=Piilota sähköpostiosoite
keep_email_private_popup=Sähköpostiosoitteesi on piilotettu muilta käyttäjiltä.
openid_desc=OpenID mahdollistaa todentamisen delegoinnin ulkopuoliselle palvelun tarjoajalle.
@@ -422,10 +545,35 @@ ssh_helper=Tarvitsetko apua? Tutustu GitHubin oppaaseen Tarvitsetko apua? Katso GitHubin opas GPG :stä.
add_new_key=Lisää SSH avain
add_new_gpg_key=Lisää GPG-avain
+key_content_ssh_placeholder=Alkaa sanoilla 'ssh-ed25519', 'ssh-rsa', 'ecdsa-sha2-nistp256', 'ecdsa-sha2-nistp384', 'ecdsa-sha2-nistp521', 'sk-ecdsa-sha2-nistp256@openssh.com', tai 'sk-ssh-ed25519@openssh.com'
+key_content_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP PUBLIC KEY BLOCK-----'
+ssh_key_name_used=Samanniminen SSH avain on jo olemassa tililläsi.
+gpg_key_id_used=Julkinen GPG-avain samalla tunnuksella on jo olemassa.
+gpg_no_key_email_found=Tämä GPG-avain ei vastaa mitään tiliisi liitettyä aktivoitua sähköpostiosoitetta. Se voidaan silti lisätä, jos allekirjoitat annetun pääsymerkin.
+gpg_key_verified=Vahvistettu avain
+gpg_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita tämän avaimen kaikkien vastaavien identiteettien lisäksi.
+gpg_key_verify=Vahvista
+gpg_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille
+gpg_token=Pääsymerkki
+gpg_token_help=Voit luoda allekirjoituksen käyttäen:
+gpg_token_code=echo "%s" | gpg -a --default-key %s --detach-sig
+gpg_token_signature=Panssaroitu GPG-allekirjoitus
+key_signature_gpg_placeholder=Alkaa sanoilla '-----BEGIN PGP SIGNATURE-----'
+verify_gpg_key_success=GPG-avain '%s' on vahvistettu.
+ssh_key_verified=Vahvistettu avain
+ssh_key_verified_long=Avain on vahvistettu pääsymerkillä ja sitä voidaan käyttää todentamaan commitit, jotka vastaavat tämän käyttäjän aktivoituja sähköpostiosoitteita.
+ssh_key_verify=Vahvista
+ssh_token_required=Sinun täytyy antaa allekirjoitus alla olevalle pääsymerkille
+ssh_token=Pääsymerkki
+ssh_token_help=Voit luoda allekirjoituksen käyttäen:
+ssh_token_signature=Panssaroitu SSH-allekirjoitus
+key_signature_ssh_placeholder=Alkaa sanoilla '-----BEGIN SSH SIGNATURE-----'
+verify_ssh_key_success=SSH avain '%s' on vahvistettu.
subkeys=Aliavaimet
key_id=Avain ID
key_name=Avaimen nimi
key_content=Sisältö
+principal_content=Sisältö
add_key_success=SSH-avain '%s' on lisätty.
add_gpg_key_success=GPG-avain '%s' lisättiin.
delete_key=Poista
@@ -435,13 +583,22 @@ gpg_key_deletion_desc=GPG-avaimen poistaminen peruuttaa sillä allekirjoitettuje
gpg_key_deletion_success=GPG-avain on poistettu.
add_on=Lisätty
valid_until=Vanhenee
+valid_forever=Voimassa ikuisesti
last_used=Käytetty viimeksi
no_activity=Ei viimeaikaista toimintaa
+can_read_info=Luku
+can_write_info=Kirjoitus
+show_openid=Näytä profiilissa
+hide_openid=Piilota profiilista
+ssh_disabled=SSH pois käytöstä
manage_social=Hallitse liitettyjä sosiaalisia tilejä
+manage_access_token=Hallitse pääsymerkkejä
generate_new_token=Luo uusi pääsymerkki
+new_token_desc=Pääsymerkkiä käyttävillä sovelluksilla on täysi pääsy tiliisi.
token_name=Pääsymerkin nimi
generate_token=Luo pääsymerkki
+generate_token_success=Uusi pääsymerkkisi on nyt luotu. Kopioi se nyt, koska sitä ei näytetä enää uudelleen.
delete_token=Poista
access_token_deletion=Poista pääsymerkki
@@ -459,8 +616,15 @@ oauth2_application_edit=Muokkaa
twofa_desc=Kaksivaiheinen todennus parantaa tilisi turvallisuutta.
+twofa_is_enrolled=Tilisi käyttää kaksivaiheista vahvistusta.
+twofa_not_enrolled=Tilisi ei tällä hetkellä käytä kaksivaiheista vahvistusta.
+twofa_enroll=Ota kaksivaiheinen vahvistus käyttöön
twofa_disabled=Kaksivaiheinen todennus on otettu pois käytöstä.
+scan_this_image=Skannaa tämä kuva tunnistautumissovelluksellasi:
+or_enter_secret=Tai kirjoita salainen avain: %s
+twofa_enrolled=Tiliisi on otettu käyttöön kaksivaiheinen vahvistus. Ota palautustunnus (%s) talteen turvalliseen paikkaan, sillä se näytetään vain kerran!
+webauthn_nickname=Nimimerkki
manage_account_links=Hallitse linkitettyjä tilejä
manage_account_links_desc=Nämä ulkoiset tilit on linkitetty Gitea tiliisi.
@@ -476,37 +640,61 @@ delete_prompt=Tämä toiminto poistaa käyttäjätilisi pysyvästi. Toimintoa Voit siirtää repon.
owner=Omistaja
+owner_helper=Jotkin organisaatiot eivät välttämättä näy pudotusvalikossa, koska repojen maksimimäärää on rajoitettu.
repo_name=Repon nimi
repo_name_helper=Hyvä repon nimi on lyhyt, mieleenpainuva ja yksilöllinen.
+repo_size=Repon koko
template=Malli
template_select=Valitse malli.
+template_helper=Tee reposta mallipohja
visibility=Näkyvyys
visibility_description=Vain omistaja tai organisaation jäsenet, jos heillä on oikeudet, voivat nähdä sen.
visibility_helper=Tee reposta yksityinen
+visibility_helper_forced=Sivuston ylläpitäjä pakottaa uudet repot olemaan yksityisiä.
fork_repo=Forkkaa repo
fork_from=Forkkaa lähteestä
fork_visibility_helper=Forkatun repon näkyvyyttä ei voi muuttaa.
+clone_in_vsc=Kloonaa VS Codessa
+download_zip=Lataa ZIP
+download_tar=Lataa TAR.GZ
repo_desc=Kuvaus
repo_lang=Kieli
repo_gitignore_helper=Valitse .gitignore mallit.
issue_labels=Ongelmien tunnisteet
+issue_labels_helper=Valitse pohja ongelmien nimilapuille.
license=Lisenssi
license_helper=Valitse lisenssitiedosto.
readme=README
auto_init=Alusta repo (Luo .gitignore, License ja README)
create_repo=Luo repo
default_branch=Oletus branch
+mirror_prune=Karsi
watchers=Tarkkailijat
stargazers=Tähtiharrastajat
forks=Haarat
pick_reaction=Valitse reaktiosi
+delete_preexisting_label=Poista
+desc.private=Yksityinen
+desc.public=Julkinen
+desc.private_template=Yksityinen malli
+desc.public_template=Malli
+desc.internal=Sisäinen
+template.git_hooks=Git-koukut
+template.webhooks=Webkoukut
template.topics=Aiheet
template.avatar=Profiilikuva
template.issue_labels=Ongelmien tunnisteet
@@ -522,15 +710,18 @@ migrate_items_pullrequests=Vetopyynnöt
migrate_items_releases=Julkaisut
migrate_repo=Siirrä repo
migrate.clone_address=Migraation / Kloonaa URL osoitteesta
+migrate.github_token_desc=Voit laittaa yhden tai useamman pääsymerkin pilkulla erotellen tähän nopeuttaaksesi migraatiota GitHub APIn vauhtirajojen takia. VAROITUS: Tämän ominaisuuden väärinkäyttö voi rikkoa palveluntarjoajan ehtoja ja johtaa tilin estämiseen.
migrate.permission_denied=Sinun ei sallita tuovan paikallisia repoja.
migrate.failed=Siirto epäonnistui: %v
+migrate.migrate_items_options=Pääsymerkki vaaditaan lisäkohteiden siirtämiseen
+migrate.migrating_failed.error=Virhe: %s
mirror_from=peilaus alkaen
forked_from=forkattu lähteestä
unwatch=Lopeta tarkkailu
watch=Tarkkaile
-unstar=Peru ääni
-star=Äänestä
+unstar=Poista tähti
+star=Tähti
download_archive=Lataa varasto
no_desc=Ei kuvausta
@@ -550,7 +741,10 @@ labels=Tunnisteet
milestones=Merkkipaalut
commits=Commitit
+commit=Commit
releases=Julkaisut
+tag=Tagi
+released_this=julkaisi tämän
file_raw=Raaka
file_history=Historia
file_view_raw=Näytä raaka
@@ -558,6 +752,8 @@ file_permalink=Pysyvä linkki
video_not_supported_in_browser=Selaimesi ei tue HTML5 video-tagia.
audio_not_supported_in_browser=Selaimesi ei tue HTML5 audio-tagia.
+blame=Selitys
+download_file=Lataa tiedosto
normal_view=Normaali näkymä
line=rivi
lines=rivejä
@@ -586,6 +782,7 @@ editor.create_new_branch_np=Luo uusi haara tälle commitille.
editor.cancel=Peruuta
editor.filename_cannot_be_empty=Tiedostonimi ei voi olla tyhjä.
editor.filename_is_invalid=Tiedostonnimi on epäkelpo: '%s'.
+editor.branch_already_exists=Haara '%s' on jo olemassa tässä repossa.
editor.no_changes_to_show=Ei muutoksia näytettäväksi.
editor.add_subdir=Lisää hakemisto…
editor.unable_to_upload_files=Tiedostojen lataaminen kohteeseen '%s' epäonnistui virheellä: %v
@@ -601,9 +798,32 @@ commits.date=Päivämäärä
commits.older=Vanhemmat
commits.newer=Uudemmat
commits.signed_by=Allekirjoittanut
-
-
-
+commits.gpg_key_id=GPG avaimen ID
+commits.ssh_key_fingerprint=SSH avaimen sormenjälki
+
+
+
+projects=Projektit
+projects.description_placeholder=Kuvaus
+projects.create=Luo projekti
+projects.title=Otsikko
+projects.new=Uusi projekti
+projects.create_success=Projekti '%s' on luotu.
+projects.deletion=Poista projekti
+projects.deletion_success=Projekti on poistettu.
+projects.edit=Muokkaa projektia
+projects.modify=Päivitä projekti
+projects.edit_success=Projekti '%s' on päivitetty.
+projects.type.basic_kanban=Yksinkertainen Kanban
+projects.type.uncategorized=Luokittelematon
+projects.board.edit=Muokkaa luetteloa
+projects.board.new_submit=Lähetä
+projects.board.new=Uusi taulu
+projects.board.set_default=Aseta oletukseksi
+projects.board.delete=Poista taulu
+projects.board.color=Väri
+projects.open=Avaa
+projects.close=Sulje
issues.desc=Ongelmien, tehtävien ja merkkipaalujen hallinta.
issues.filter_milestones=Suodata merkkipaalu
@@ -620,12 +840,14 @@ issues.new.closed_milestone=Suljetut merkkipaalut
issues.new.assignees=Käsittelijä
issues.new.clear_assignees=Tyhjennä käsittelijä
issues.new.no_assignees=Ei käsittelijää
+issues.choose.blank=Oletus
issues.no_ref=Haaraa/tagia ei määritelty
issues.create=Ilmoita ongelma
issues.new_label=Uusi tunniste
issues.new_label_placeholder=Tunnisteen nimi
issues.new_label_desc_placeholder=Kuvaus
issues.create_label=Luo tunniste
+issues.label_templates.helper=Valitse tunnistejoukko
issues.add_milestone_at=`lisäsi tämän merkkipaaluun %s %s`
issues.deleted_milestone=`(poistettu)`
issues.self_assign_at=`itse otti tämän käsittelyyn %s`
@@ -641,6 +863,7 @@ issues.filter_type.all_issues=Kaikki ongelmat
issues.filter_type.assigned_to_you=Osoitettu sinulle
issues.filter_type.created_by_you=Ilmoittamasi
issues.filter_type.mentioning_you=Jotka mainitsee sinut
+issues.filter_type.review_requested=Arvostelua pyydetty
issues.filter_sort=Lajittele
issues.filter_sort.latest=Uusin
issues.filter_sort.oldest=Vanhin
@@ -658,6 +881,7 @@ issues.action_open=Avaa
issues.action_close=Sulje
issues.action_label=Tunniste
issues.action_milestone=Merkkipaalu
+issues.action_milestone_no_select=Ei merkkipaalua
issues.opened_by=%[1]s avasi %[3]s
issues.previous=Edellinen
issues.next=Seuraava
@@ -725,9 +949,11 @@ issues.add_time_minutes=Minuuttia
issues.add_time_sum_to_small=Aikaa ei syötetty.
issues.time_spent_from_all_authors=`Käytetty kokonaisaika: %s`
issues.due_date=Määräpäivä
+issues.due_date_form=vvvv-kk-pp
issues.due_date_form_edit=Muokkaa
issues.due_date_form_remove=Poista
issues.due_date_not_set=Määräpäivää ei asetettu.
+issues.due_date_overdue=Myöhässä
issues.dependency.title=Riippuvuudet
issues.dependency.add=Lisää riippuvuus…
issues.dependency.cancel=Peru
@@ -735,6 +961,12 @@ issues.dependency.remove=Poista
issues.dependency.remove_info=Poistä tämä riippuvuus
issues.review.self.approval=Et voi hyväksyä omia vetopyyntöjä.
issues.review.approve=hyväksyi nämä muutokset %s
+issues.review.left_comment=jätti kommentin
+issues.review.pending=Odottaa
+issues.reference_issue.body=Kuvaus
+issues.content_history.deleted=poistettu
+issues.content_history.edited=muokattu
+issues.content_history.created=luotu
pulls.new=Uusi pull pyyntö
@@ -776,12 +1008,17 @@ milestones.edit_success=Merkkipaalu '%s' on päivitetty.
milestones.filter_sort.most_issues=Eniten ongelmia
milestones.filter_sort.least_issues=Vähiten ongelmia
+signing.wont_sign.always=Commitit ovat aina allekirjoitettuja
wiki=Wiki
+wiki.welcome=Tervetuloa Wikiin.
+wiki.welcome_desc=Wikissä voit kirjoittaa ja jakaa dokumentaatiota käyttäjien kesken.
+wiki.create_first_page=Luo ensimmäinen sivu
wiki.page=Sivu
wiki.filter_page=Suodatin sivu
wiki.new_page=Sivu
+wiki.default_commit_message=Kirjoita muistiinpano tästä päivityksestä (valinnainen).
wiki.save_page=Tallenna sivu
wiki.last_commit_info=%s muokkasi tätä sivua %s
wiki.edit_page_button=Muokkaa
@@ -814,6 +1051,7 @@ activity.new_issues_count_n=Uutta ongelmaa
activity.new_issue_label=Avoinna
activity.unresolved_conv_label=Auki
activity.published_release_label=Julkaistu
+activity.git_stats_pushed_1=on työntänyt
activity.git_stats_file_1=%d tiedosto
activity.git_stats_file_n=%d tiedostoa
activity.git_stats_addition_1=%d lisäys
@@ -850,6 +1088,7 @@ settings.danger_zone=Vaaravyöhyke
settings.new_owner_has_same_repo=Uudella omistajalla on jo samanniminen repo. Ole hyvä ja valitse toinen nimi.
settings.transfer=Siirrä omistajuus
settings.transfer_form_title=Syötä repon nimi vahvistuksena:
+settings.transfer_notices_3=- Jos arkisto on yksityinen ja se siirretään yksittäiselle käyttäjälle, tämä toiminto varmistaa, että käyttäjällä on ainakin lukuoikeudet (ja muuttaa käyttöoikeuksia tarvittaessa).
settings.transfer_owner=Uusi omistaja
settings.wiki_delete=Poista Wiki data
settings.wiki_delete_desc=Repon wikin data poistaminen on pysyvä eikä voi peruuttaa.
@@ -882,43 +1121,96 @@ settings.discord_username=Käyttäjätunnus
settings.event_create=Luo
settings.event_delete=Poista
settings.event_release_desc=Julkaisu julkaistu, päivitetty tai poistettu varastosta.
+settings.event_push=Työnnä
settings.event_repository=Repo
settings.event_issue_comment_desc=Ongelman kommentti luotu, muokattu tai poistettu.
settings.event_pull_request=Vetopyyntö
settings.update_webhook=Päivitä webkoukku
+settings.delete_webhook=Poista webkoukku
settings.recent_deliveries=Viimeisimmät toimitukset
settings.hook_type=Koukkutyyppi
settings.slack_token=Pääsymerkki
settings.slack_domain=Verkkotunnus
settings.slack_channel=Kanava
-settings.deploy_keys=Deploy avaimet
-settings.add_deploy_key=Lisää deploy avain
+settings.web_hook_name_gitea=Gitea
+settings.web_hook_name_gogs=Gogs
+settings.web_hook_name_slack=Slack
+settings.web_hook_name_discord=Discord
+settings.web_hook_name_dingtalk=DingTalk
+settings.web_hook_name_telegram=Telegram
+settings.web_hook_name_matrix=Matrix
+settings.web_hook_name_feishu=Feishu
+settings.web_hook_name_larksuite=Lark Suite
+settings.web_hook_name_packagist=Packagist
+settings.deploy_keys=Julkaisuavaimet
+settings.add_deploy_key=Lisää julkaisuavain
+settings.deploy_key_desc=Julkaisuavaimilla on vain-luku oikeudet repoon.
+settings.is_writable_info=Salli tämän julkaisuavaimen puskea repoon.
+settings.no_deploy_keys=Julkaisuavaimia ei ole käytössä vielä.
settings.title=Otsikko
settings.deploy_key_content=Sisältö
+settings.key_been_used=Julkaisuavain identtisellä sisällöllä on jo käytössä.
+settings.key_name_used=Julkaisuavain samalla nimellä on jo olemassa.
+settings.add_key_success=Julkaisuavain '%s' on lisätty.
+settings.deploy_key_deletion=Poista julkaisuavain
+settings.deploy_key_deletion_desc=Julkaisuavaimen poistaminen kumoaa sen pääsyn tähän repoon. Jatketaanko?
+settings.deploy_key_deletion_success=Julkaisuavain on poistettu.
settings.branches=Haarat
settings.protected_branch=Haaran suojaus
settings.branch_protection=Haaran '%s ' suojaus
settings.protect_this_branch=Ota haaran suojaus käyttöön
+settings.protect_whitelist_deploy_keys=Lisää julkaisuavaimet sallittujen listalle mahdollistaaksesi repohin kirjoituksen.
settings.protect_whitelist_users=Lista käyttäjistä joilla työntö oikeus:
settings.protect_whitelist_search_users=Etsi käyttäjiä…
settings.protect_merge_whitelist_committers_desc=Salli vain listaan merkittyjen käyttäjien ja tiimien yhdistää vetopyynnöt tähän haaraan.
settings.protect_merge_whitelist_users=Lista käyttäjistä joilla yhdistämis-oikeus:
settings.protect_required_approvals=Vaadittavat hyväksynnät:
settings.protect_approvals_whitelist_users=Sallittujen tarkastajien lista:
+settings.protect_protected_file_patterns_desc=Suojatut tiedostot, joita ei voi muuttaa suoraan, vaikka käyttäjällä olisi oikeudet lisätä, muokata tai poistaa tiedostoja tässä haarassa. Useita malleja voidaan erottaa puolipisteellä ('\;'). Katso github.com/gobwas/glob dokumentaatio mallisyntaksille. Esimerkkejä: .drone.yml
, /docs/**/*.txt
.
+settings.protect_unprotected_file_patterns_desc=Suojaamattomat tiedostot, joita voidaan muuttaa suoraan, jos käyttäjällä on kirjoitusoikeudet, ohittaen push-rajoituksen. Useita kuvioita voidaan erottaa puolipisteellä ('\;'). Katso github.com/gobwas/glob dokumentaatio kuviosyntaksille. Esimerkkejä: .drone.yml
, /docs/**/*.txt
.
settings.update_protect_branch_success=Haaran '%s' suojaus on päivitetty.
settings.remove_protected_branch_success=Haaran '%s' suojaus on poistettu käytöstä.
settings.choose_branch=Valitse haara…
settings.no_protected_branch=Suojattuja haaroja ei ole.
settings.edit_protected_branch=Muokkaa
settings.protected_branch_required_approvals_min=Vaadittavat hyväksynnät ei voi olla negatiivinen.
+settings.tags=Tagit
+settings.tags.protection.pattern=Tagin kuvio
+settings.tags.protection.pattern.description=Voit käyttää yhtä nimeä tai glob-kuviota tai säännöllistä lauseketta, joka täsmää useisiin tageihin. Lue lisää suojatut tagit oppaasta .
+settings.bot_token=Botti pääsymerkki
+settings.matrix.homeserver_url=Kotipalvelimen URL
+settings.matrix.access_token=Pääsymerkki
settings.archive.button=Arkistoi repo
settings.archive.header=Arkistoi tämä repo
settings.lfs=LFS
+settings.lfs_filelist=LFS-tiedostot tallennettu tähän repoon
+settings.lfs_no_lfs_files=LFS-tiedostoja ei ole tallennettu tähän repoon.
+settings.lfs_findcommits=Etsi commitit
+settings.lfs_lfs_file_no_commits=LFS-tiedostolle ei löytynyt committeja
+settings.lfs_noattribute=Tällä polulla ei ole lukittavaa attribuuttia oletushaarassa
+settings.lfs_delete=Poista LFS-tiedosto OID:lla %s
+settings.lfs_delete_warning=LFS-tiedoston poistaminen voi aiheuttaa 'object does not exists'-virheitä checkouttattaessa. Oletko varma?
+settings.lfs_findpointerfiles=Etsi osoitintiedostoja
+settings.lfs_locks=Lukot
+settings.lfs_invalid_locking_path=Virheellinen polku: %s
+settings.lfs_invalid_lock_directory=Hakemistoa ei voida lukita: %s
+settings.lfs_lock_already_exists=Lukitus on jo olemassa: %s
+settings.lfs_lock_path=Lukittavan tiedostopolku...
+settings.lfs_locks_no_locks=Ei lukkoja
+settings.lfs_lock_file_no_exist=Lukittua tiedostoa ei ole olemassa oletushaarassa
+settings.lfs_force_unlock=Pakota lukituksen avaus
+settings.lfs_pointers.found=Löytyi %d blob osoitinta - %d yhdistettyö, %d yhdistämätöntä (%d puuttuu varastosta)
+settings.lfs_pointers.sha=Blob SHA
settings.lfs_pointers.oid=OID
+settings.lfs_pointers.inRepo=Repossa
+settings.lfs_pointers.exists=Löytyy varastosta
+settings.lfs_pointers.accessible=Saatavilla käyttäjälle
diff.browse_source=Selaa lähdekoodia
diff.parent=vanhempi
+diff.commit=commit
diff.git-notes=Muistiinpanot
+diff.options_button=Vertailun asetukset
diff.show_split_view=Jaettu näkymä
diff.show_unified_view=Yhdistetty näkymä
diff.whitespace_button=Tyhjämerkki
@@ -938,6 +1230,7 @@ diff.review.comment=Kommentoi
diff.review.approve=Hyväksy
release.releases=Julkaisut
+release.tags=Tagit
release.new_release=Uusi julkaisu
release.draft=Työversio
release.prerelease=Esiversio
@@ -964,6 +1257,7 @@ release.downloads=Lataukset
branch.name=Haaran nimi
branch.delete_head=Poista
branch.delete=Poista haara '%s'
+branch.create_branch=Luo haara %s
@@ -1003,7 +1297,9 @@ settings.permission=Käyttöoikeudet
settings.visibility=Näkyvyys
settings.visibility.public=Julkinen
settings.visibility.limited=Rajoitettu (näkyvä vain kirjautuneille käyttäjille)
+settings.visibility.limited_shortname=Rajattu
settings.visibility.private=Yksityinen (näkyvä vain organisaation jäsenille)
+settings.visibility.private_shortname=Yksityinen
settings.update_settings=Päivitä asetukset
settings.delete=Poista organisaatio
@@ -1054,6 +1350,7 @@ users=Käyttäjätilit
organizations=Organisaatiot
repositories=Repot
authentication=Todennuslähteet
+emails=Käyttäjien sähköpostit
config=Asetukset
notices=Järjestelmän ilmoitukset
monitor=Valvonta
@@ -1062,10 +1359,13 @@ last_page=Viimeisin
total=Yhteensä: %d
dashboard.statistic=Yhteenveto
+dashboard.operations=Huoltotoimet
dashboard.system_status=Järjestelmän tila
dashboard.operation_name=Toiminnon nimi
dashboard.operation_switch=Vaihda
dashboard.operation_run=Suorita
+dashboard.delete_inactive_accounts=Poista kaikki aktivoimattomat käyttäjät
+dashboard.delete_repo_archives=Poista kaikki repojen arkistot (ZIP, TAR.GZ, jne..)
dashboard.server_uptime=Palvelimen Uptime
dashboard.current_goroutine=Nykyiset Goroutinet
dashboard.current_memory_usage=Nykyinen muistinkäyttö
@@ -1100,23 +1400,48 @@ users.name=Käyttäjätunnus
users.full_name=Kokonimi
users.activated=Aktivoitu
users.admin=Ylläpito
+users.restricted=Rajoitettu
+users.2fa=2FA
users.repos=Repot
users.created=Luotu
users.last_login=Viimeksi kirjautunut
+users.never_login=Ei koskaan kirjautunut
users.edit=Muokkaa
users.auth_source=Todennuslähde
users.local=Paikallinen
users.password_helper=Jätä salasanakenttä tyhjäksi jos haluat pitää sen muuttamattomana.
users.update_profile_success=Käyttäjän tili on päivitetty.
users.edit_account=Muokkaa käyttäjän tiliä
+users.max_repo_creation_desc=(Aseta -1 käyttääksesi globaalia oletusrajaa.)
+users.is_activated=Käyttäjätili on aktivoitu
+users.prohibit_login=Ota sisäänkirjautuminen pois käytöstä
+users.is_admin=Ylläpitäjä
+users.is_restricted=Rajoitettu tili
+users.allow_git_hook=Voi luoda Git koukkuja
+users.allow_create_organization=Voi luoda organisaatioita
users.update_profile=Päivitä käyttäjän tili
users.delete_account=Poista käyttäjän tili
+users.list_status_filter.menu_text=Suodata
+users.list_status_filter.reset=Tyhjennä
+users.list_status_filter.is_active=Aktiivinen
+users.list_status_filter.not_active=Ei-aktiivinen
+users.list_status_filter.is_admin=Ylläpitäjä
+users.list_status_filter.not_admin=Ei ylläpitäjä
+users.list_status_filter.is_restricted=Rajoitettu
+users.list_status_filter.not_restricted=Ei rajoitettu
+users.list_status_filter.is_prohibit_login=Kirjautuminen estetty
+users.list_status_filter.not_prohibit_login=Kirjautuminen sallittu
+users.list_status_filter.is_2fa_enabled=2FA käytössä
+users.list_status_filter.not_2fa_enabled=2FA ei käytössä
emails.email_manage_panel=Käyttäjien sähköpostien hallinta
emails.primary=Ensisijainen
emails.activated=Aktivoitu
emails.filter_sort.email=Sähköposti
+emails.filter_sort.email_reverse=Sähköposti (käänteinen)
emails.filter_sort.name=Käyttäjänimi
+emails.filter_sort.name_reverse=Käyttäjänimi (käänteinen)
+emails.duplicate_active=Tämä sähköpostiosoite on jo käytössä toisella käyttäjällä.
orgs.org_manage_panel=Organisaatioiden hallinta
orgs.name=Nimi
@@ -1129,11 +1454,12 @@ repos.owner=Omistaja
repos.name=Nimi
repos.private=Yksityinen
repos.watches=Tarkkailijat
-repos.stars=Äänet
+repos.stars=Tähdet
repos.forks=Haarat
repos.issues=Ongelmat
repos.size=Koko
+packages.owner=Omistaja
@@ -1155,12 +1481,14 @@ auths.user_dn=Käyttäjä DN
auths.search_page_size=Sivukoko
auths.filter=Käyttäjäsuodatin
auths.admin_filter=Ylläpitosuodatin
+auths.restricted_filter=Rajoitettu suodatin
auths.smtp_auth=SMTP todennustyyppi
auths.smtphost=SMTP isäntä
auths.smtpport=SMTP portti
auths.allowed_domains=Sallitut verkkotunnukset
auths.skip_tls_verify=Ohita TLS tarkistaminen
auths.pam_service_name=PAM palvelun nimi
+auths.oauth2_tokenURL=Pääsymerkki URL
auths.enable_auto_register=Ota käyttöön automaattinen rekisteröinti
auths.tips=Vinkit
auths.tips.oauth2.general=OAuth2-autentikointi
@@ -1217,9 +1545,7 @@ config.queue_length=Jonon pituus
config.deliver_timeout=Toimitus aikakatkaisu
config.mailer_enabled=Käytössä
-config.mailer_disable_helo=Poista käytöstä HELO
config.mailer_name=Nimi
-config.mailer_host=Isäntä
config.mailer_user=Käyttäjä
config.oauth_config=OAuth asetukset
@@ -1285,6 +1611,8 @@ notices.op=Toiminta
create_repo=luotu repo %s
rename_repo=uudelleennimetty repo %[1]s
nimelle %[3]s
transfer_repo=siirretty repo %s
kohteeseen %s
+push_tag=työnsi tagin %[3]s kohteeseen %[4]s
+compare_commits_general=Vertaa committeja
[tool]
ago=%s sitten
@@ -1324,8 +1652,29 @@ mark_as_unread=Merkitse lukemattomaksi
mark_all_as_read=Merkitse kaikki luetuiksi
[gpg]
+error.no_committer_account=Committaajan sähköpostiosoitteeseen ei ole linkitetty tiliä
+error.not_signed_commit=Ei allekirjoitettu committi
[units]
[packages]
+title=Paketit
+desc=Hallitse repon paketteja.
+empty=Täällä ei vielä ole paketteja.
+empty.documentation=Lisätietoa pakettirekisteristä löydät dokumentaatiosta .
+filter.type=Tyyppi
+filter.type.all=Kaikki
+filter.no_result=Suodattimesi ei tuottanut tuloksia.
+installation=Asennus
+details.author=Tekijä
+composer.documentation=Lisätietoa Composer-rekisteristä löydät dokumentaatiosta .
+conan.documentation=Lisätietoa Conan-rekisteristä löydät dokumentaatiosta .
+container.documentation=Lisätietoa Container-rekisteristä löydätdokumentaatiosta .
+generic.documentation=Lisätietoa yleisestä pakettirekisteristä löydät dokumentaatiosta .
+helm.documentation=Lisätietoa Helm-rekisteristä löydät dokumentaatiosta .
+maven.documentation=Lisätietoa Maven-rekisteristä löydät dokumentaatiosta .
+nuget.documentation=Lisätietoa NuGet-rekisteristä löydät dokumentaatiosta .
+npm.documentation=Lisätietoa npm-rekisteristä löydät dokumentaatiosta .
+pypi.documentation=Lisätietoa PyPI-rekisteristä löydät dokumentaatiosta .
+rubygems.documentation=Lisätietoa RubyGems-rekisteristä löydät dokumentaatiosta .
diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini
index acd17f88c595..18eb44b16a3d 100644
--- a/options/locale/locale_fr-FR.ini
+++ b/options/locale/locale_fr-FR.ini
@@ -9,7 +9,6 @@ sign_out=Déconnexion
sign_up=S'inscrire
link_account=Lier un Compte
register=S'inscrire
-website=Site web
version=Version
powered_by=Propulsé par %s
page=Page
@@ -43,6 +42,11 @@ webauthn_error=Impossible de lire votre clé de sécurité.
webauthn_unsupported_browser=Votre navigateur ne prend actuellement pas en charge WebAuthn.
webauthn_error_unknown=Une erreur indéterminée s'est produite. Veuillez réessayer.
webauthn_error_insecure=WebAuthn ne prend en charge que les connexions sécurisées. Pour les tests via HTTP, vous pouvez utiliser l'origine "localhost" ou "127.0.0.1"
+webauthn_error_unable_to_process=Le serveur n'a pas pu traiter votre demande.
+webauthn_error_duplicated=La clé de sécurité n'est pas autorisée pour cette demande. Veuillez vous assurer que la clé n'est pas déjà enregistrée.
+webauthn_error_empty=Vous devez définir un nom pour cette clé.
+webauthn_error_timeout=Le délai d'attente imparti a été atteint avant que votre clé ne puisse être lue. Veuillez recharger la page pour réessayer.
+webauthn_reload=Recharger
repository=Dépôt
organization=Organisation
@@ -103,7 +107,12 @@ never=Jamais
rss_feed=Flux RSS
[error]
+occurred=Une erreur s’est produite
+report_message=Si vous êtes sûr qu'il s'agit d'un bug de Gitea, cherchez s’il existe des tickets sur GitHub ou ouvrez-en un nouveau si nécessaire.
missing_csrf=Requête incorrecte: aucun jeton CSRF présent
+invalid_csrf=Requête incorrecte : jeton CSRF invalide
+not_found=La cible n'a pu être trouvée.
+network_error=Erreur réseau
[startpage]
app_desc=Un service Git auto-hébergé sans prise de tête
@@ -169,7 +178,8 @@ log_root_path_helper=Les fichiers de journalisation seront écrits dans ce répe
optional_title=Paramètres facultatifs
email_title=Paramètres E-mail
-smtp_host=Hôte SMTP
+smtp_addr=Hôte SMTP
+smtp_port=Port SMTP
smtp_from=Envoyer les e-mails en tant que
smtp_from_helper=Adresse e-mail utilisée par Gitea. Veuillez entrer votre e-mail directement ou sous la forme .
mailer_user=Utilisateur SMTP
@@ -260,6 +270,7 @@ search=Rechercher
code=Code
search.fuzzy=Approximative
search.match=Exacte
+code_search_unavailable=Actuellement, la recherche de code n'est pas disponible. Veuillez contacter l'administrateur de votre site.
repo_no_results=Aucun dépôt correspondant n'a été trouvé.
user_no_results=Aucun utilisateur correspondant n'a été trouvé.
org_no_results=Aucune organisation correspondante n'a été trouvée.
@@ -273,6 +284,7 @@ register_helper_msg=Déjà enregistré ? Connectez-vous !
social_register_helper_msg=Déjà inscrit ? Connectez-vous !
disable_register_prompt=Les inscriptions sont désactivées. Veuillez contacter l'administrateur du site.
disable_register_mail=La confirmation par e-mail à l'inscription est désactivée.
+manual_activation_only=Contactez l'administrateur de votre site pour terminer l'activation.
remember_me=Mémoriser cet appareil
forgot_password_title=Mot de passe oublié
forgot_password=Mot de passe oublié ?
@@ -311,6 +323,9 @@ oauth_signup_submit=Finaliser la création du compte
oauth_signin_tab=Lier à un compte existant
oauth_signin_title=Connectez-vous pour autoriser le compte lié
oauth_signin_submit=Lier un compte
+oauth.signin.error=Une erreur s'est produite lors du traitement de la demande d'autorisation. Si cette erreur persiste, veuillez contacter l'administrateur du site.
+oauth.signin.error.access_denied=La demande d'autorisation a été refusée.
+oauth.signin.error.temporarily_unavailable=L'autorisation a échoué car le serveur d'authentification est temporairement indisponible. Veuillez réessayer plus tard.
openid_connect_submit=Se connecter
openid_connect_title=Se connecter à un compte existant
openid_connect_desc=L'URI OpenID choisie est inconnue. Associez-le à un nouveau compte ici.
@@ -357,6 +372,7 @@ reset_password.text=Veuillez cliquer sur le lien suivant pour récupérer votre
register_success=Inscription réussie
+issue_assigned.pull=@%[1]s vous a assigné à la demande d’ajout %[2]s dans le dépôt %[3]s.
issue_assigned.issue=@%[1]s vous a assigné le ticket %[2]s dans le dépôt %[3]s.
issue.x_mentioned_you=@%s vous a mentionné:
@@ -972,6 +988,9 @@ file_view_rendered=Voir le rendu
file_view_raw=Voir le Raw
file_permalink=Lien permanent
file_too_large=Le fichier est trop gros pour être affiché.
+invisible_runes_line=`Cette ligne contient des caractères Unicode invisibles`
+ambiguous_runes_line=`Cette ligne contient des caractères Unicode ambigus`
+ambiguous_character=`%[1]c [U+%04[1]X] peut être confondu avec %[2]c [U+%04[2]X]`
file_copy_permalink=Copier le lien permanent
video_not_supported_in_browser=Votre navigateur ne supporte pas le tag HTML5 "video".
@@ -989,6 +1008,7 @@ normal_view=Vue normale
line=ligne
lines=lignes
+editor.add_file=Ajouter un fichier
editor.new_file=Nouveau fichier
editor.upload_file=Téléverser un fichier
editor.edit_file=Modifier le fichier
@@ -1012,6 +1032,10 @@ editor.add_tmpl=Ajouter ''
editor.add=Ajouter '%s'
editor.update=Mise à jour de '%s'
editor.delete=Supprimer '%s'
+editor.patch=Appliquer le correctif
+editor.patching=Correction:
+editor.fail_to_apply_patch=Impossible d'appliquer le correctif '%s'
+editor.new_patch=Nouveau correctif
editor.commit_message_desc=Ajouter une description détaillée facultative…
editor.signoff_desc=Ajout d'un trailer Signed-off-by par le committeur à la fin du message du journal de commit.
editor.commit_directly_to_this_branch=Soumettre directement dans la branche %s .
@@ -1036,6 +1060,8 @@ editor.commit_empty_file_text=Le fichier que vous allez commiter est vide. Conti
editor.no_changes_to_show=Il n’y a aucun changement à afficher.
editor.fail_to_update_file=Impossible de mettre à jour/créer le fichier '%s'.
editor.fail_to_update_file_summary=Message d'erreur :
+editor.push_rejected_no_message=La modification a été rejetée par le serveur sans message. Veuillez vérifier les Git Hooks.
+editor.push_rejected=La modification a été rejetée par le serveur. Veuillez vérifier vos Git Hooks.
editor.push_rejected_summary=Message de rejet complet :
editor.add_subdir=Ajouter un dossier…
editor.unable_to_upload_files=Échec lors de l'envoie du fichier '%s' avec l’erreur : %v
@@ -1045,6 +1071,7 @@ editor.cannot_commit_to_protected_branch=Impossible de créer une révision sur
editor.no_commit_to_branch=Impossible d'enregistrer la révisions directement sur la branche parce que :
editor.user_no_push_to_branch=L'utilisateur ne peut pas pousser vers la branche
editor.require_signed_commit=Cette branche nécessite une révision signée
+editor.cherry_pick=Picorer %s vers:
editor.revert=Rétablir %s sur:
commits.desc=Naviguer dans l'historique des modifications.
@@ -1064,7 +1091,15 @@ commits.signed_by=Signé par
commits.signed_by_untrusted_user=Signé par un utilisateur non approuvé
commits.signed_by_untrusted_user_unmatched=Signé par un utilisateur non fiable qui ne correspond pas au validateur
commits.gpg_key_id=ID de la clé GPG
+commits.ssh_key_fingerprint=Empreinte numérique de la clé SSH
+commit.actions=Actions
+commit.revert=Rétablir
+commit.revert-header=Rétablir : %s
+commit.revert-content=Sélectionnez la branche sur laquelle revenir :
+commit.cherry-pick=Picorer
+commit.cherry-pick-header=Picorer : %s
+commit.cherry-pick-content=Sélectionner la branche à picorer :
ext_issues.desc=Lien vers un gestionnaire de tickets externe.
@@ -1384,6 +1419,7 @@ compare.compare_head=comparer
pulls.desc=Activer les demandes de fusion et la revue de code.
pulls.new=Nouvelle demande d'ajout
+pulls.view=Voir la demande d'ajout
pulls.compare_changes=Nouvelle demande de fusion
pulls.compare_changes_desc=Sélectionnez la branche dans laquelle fusionner et la branche depuis laquelle tirer les modifications.
pulls.compare_base=fusionner dans
@@ -1393,6 +1429,7 @@ pulls.filter_branch=Filtre de branche
pulls.no_results=Aucun résultat trouvé.
pulls.nothing_to_compare=Ces branches sont identiques. Il n'y a pas besoin de créer une demande de fusion.
pulls.nothing_to_compare_and_allow_empty_pr=Ces branches sont égales. Cette demande d'ajout sera vide.
+pulls.has_pull_request='Il existe déjà une demande d'ajout entre ces deux branches : %[2]s#%[3]d '
pulls.create=Créer une demande d'ajout
pulls.title_desc=veut fusionner %[1]d révision(s) depuis %[2]s
vers %[3]s
pulls.merged_title_desc=a fusionné %[1]d révision(s) à partir de %[2]s
vers %[3]s
%[4]s
@@ -1421,7 +1458,6 @@ pulls.required_status_check_missing=Certains contrôles requis sont manquants.
pulls.required_status_check_administrator=En tant qu'administrateur, vous pouvez toujours fusionner cette requête de pull.
pulls.blocked_by_approvals=Cette demande d'ajout n'a pas assez d'approbation. %d sur %d approbations accordées.
pulls.blocked_by_rejection=Cette demande de fusion a des modifications demandées par un réviseur officiel.
-pulls.blocked_by_official_review_requests=Cette demande d'ajout a des demandes de revue officielles.
pulls.blocked_by_outdated_branch=Cette demande d'ajout est bloquée car elle est obsolète.
pulls.blocked_by_changed_protected_files_1=Cette demande d'ajout est bloquée car elle modifie un fichier protégé :
pulls.blocked_by_changed_protected_files_n=Cette Pull Request est bloquée car elle modifie les fichiers protégés :
@@ -1443,6 +1479,10 @@ pulls.no_merge_helper=Activez des options de fusion dans les paramètres du dép
pulls.no_merge_wip=Cette demande d'ajout ne peut pas être fusionnée car elle est marquée comme en cours de chantier.
pulls.no_merge_not_ready=Cette demande d'ajout n'est pas prête à être fusionnée, vérifiez l'état de la revue et les vérifications.
pulls.no_merge_access=Vous n'êtes pas autorisé⋅e à fusionner cette demande d'ajout.
+pulls.merge_pull_request=Créer une révision de fusion
+pulls.rebase_merge_pull_request=Rebaser puis avancer rapidement
+pulls.rebase_merge_commit_pull_request=Rebaser puis créer une révision de fusion
+pulls.squash_merge_pull_request=Créer une révision de concaténation
pulls.merge_manually=Fusionné manuellement
pulls.merge_commit_id=L'ID de la révision de fusion
pulls.require_signed_wont_sign=La branche nécessite des révisions signées mais cette fusion ne sera pas signée
@@ -1473,9 +1513,17 @@ pulls.merge_instruction_hint=`Vous pouvez également voir %s
rename_repo=a rebaptisé le dépôt de %[1]s
vers %[3]s
+create_pull_request=`a créé la demande d'ajout %[3]s#%[2]s `
+close_pull_request=`a fermé la demande d'ajout %[3]s#%[2]s `
+reopen_pull_request=`a réouvert la demande d'ajout %[3]s#%[2]s `
+comment_pull=`a commenté la demande d'ajout %[3]s#%[2]s `
+merge_pull_request=`a fusionné la demande d'ajout %[3]s#%[2]s `
transfer_repo=a transféré le dépôt %s
à %s
delete_tag=étiquette supprimée %[2]s de %[3]s
delete_branch=branche %[2]s supprimée de %[3]s
@@ -2647,6 +2698,8 @@ compare_branch=Comparer
compare_commits=Comparer %d révisions
compare_commits_general=Comparer les révisions
mirror_sync_delete=a synchronisé puis supprimé la nouvelle référence %[2]s
vers %[3]s depuis le miroir
+approve_pull_request=`a approuvé %[3]s#%[2]s `
+reject_pull_request=`a suggérés des changements pour %[3]s#%[2]s `
review_dismissed_reason=Raison :
[tool]
diff --git a/options/locale/locale_hu-HU.ini b/options/locale/locale_hu-HU.ini
index a98bbedf3e84..c996aef38560 100644
--- a/options/locale/locale_hu-HU.ini
+++ b/options/locale/locale_hu-HU.ini
@@ -8,7 +8,6 @@ sign_out=Kijelentkezés
sign_up=Regisztrálás
link_account=Fiók kapcsolása
register=Regisztráció
-website=Webhely
version=Verzió
powered_by=Biztosítja: %s
page=Oldal
@@ -135,7 +134,6 @@ log_root_path_helper=A naplófájlok ebbe a mappába fognak íródni.
optional_title=További beállítások
email_title=E-mail beállítások
-smtp_host=SMTP kiszolgáló
smtp_from=E-mail küldése mint
smtp_from_helper=Az E-mail cím a mit a Gitea használni fog. Megadhatja sima email címként vagy "Név" formátumban.
mailer_user=SMTP-felhasználónév
@@ -1625,11 +1623,8 @@ config.queue_length=Várakozási Sor Hossza
config.deliver_timeout=Kézbesítési Időtúllépés
config.skip_tls_verify=A TLS Hitelesítés Kihagyása
-config.mailer_config=SMTP levelező Beállítások
config.mailer_enabled=Engedélyezett
-config.mailer_disable_helo=HELO Letiltása
config.mailer_name=Név
-config.mailer_host=Kiszolgáló
config.mailer_user=Felhasználó
config.mailer_use_sendmail=Sendmail Használata
config.mailer_sendmail_path=Sendmail Elérési Útja
diff --git a/options/locale/locale_id-ID.ini b/options/locale/locale_id-ID.ini
index 34c7db6b23ea..e7ddd418c62e 100644
--- a/options/locale/locale_id-ID.ini
+++ b/options/locale/locale_id-ID.ini
@@ -8,7 +8,6 @@ sign_out=Keluar
sign_up=Daftar
link_account=Tautan Akun
register=Daftar
-website=Situs Web
version=Versi
powered_by=Diberdayakan oleh %s
page=Halaman
@@ -131,7 +130,6 @@ log_root_path_helper=Berkas log akan ditulis ke direktori ini.
optional_title=Pengaturan Opsional
email_title=Pengaturan Surel
-smtp_host=Host SMTP
smtp_from=Kirim Surel sebagai
smtp_from_helper=Alamat surel Gitea akan digunakan. Masukkan alamat surel atau gunakan fomat "Nama" .
mailer_user=Nama Pengguna SMTP
@@ -1235,11 +1233,8 @@ config.queue_length=Panjang antrian
config.deliver_timeout=Berikan waktu habis
config.skip_tls_verify=Melewatkan verifikasi TLS
-config.mailer_config=Pengaturan SMTP Mailer
config.mailer_enabled=Diaktifkan
-config.mailer_disable_helo=Nonaktifkan HELO
config.mailer_name=Nama
-config.mailer_host=Host
config.mailer_user=Pengguna
config.mailer_use_sendmail=Menggunakan Sendmail
config.mailer_sendmail_path=Jalur Sendmail
diff --git a/options/locale/locale_is-IS.ini b/options/locale/locale_is-IS.ini
index 9503c3c2778c..90979837cbb4 100644
--- a/options/locale/locale_is-IS.ini
+++ b/options/locale/locale_is-IS.ini
@@ -8,7 +8,6 @@ sign_out=Skrá Út
sign_up=Nýskráning
link_account=Tengja Notanda
register=Nýskráning
-website=Vefsíða
version=Útgáfa
powered_by=Keyrt af %s
page=Síða
@@ -177,7 +176,6 @@ log_root_path_helper=Annálaskrár verða skrifaðar í þessa möppu.
optional_title=Valfrjálsar Stillingar
email_title=Tölvupóstsstillingar
-smtp_host=SMTP Hýsill
smtp_from=Senda Tölvupóst Sem
smtp_from_helper=Netfang sem Gitea mun nota. Sláðu inn venjulegt netfang eða notaðu „Nafn“ sniðið.
mailer_user=SMTP Notandanafn
@@ -1265,7 +1263,6 @@ config.db_path=Slóð
config.mailer_name=Heiti
-config.mailer_host=Hýsill
config.mailer_user=Notandi
diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini
index 7fd829873706..ac29c5b841d4 100644
--- a/options/locale/locale_it-IT.ini
+++ b/options/locale/locale_it-IT.ini
@@ -9,7 +9,6 @@ sign_out=Esci
sign_up=Registrati
link_account=Collega account
register=Registrati
-website=Sito Web
version=Versione
powered_by=Gestito da %s
page=Pagina
@@ -179,7 +178,8 @@ log_root_path_helper=I file di log saranno scritti in questa directory.
optional_title=Impostazioni Facoltative
email_title=Impostazioni Email
-smtp_host=Host SMTP
+smtp_addr=Host SMTP
+smtp_port=Porta SMTP
smtp_from=Invia Email come
smtp_from_helper=Indirizzo Email che Gitea utilizzerà. Inserisci un indirizzo email o usa il formato "Name" .
mailer_user=Nome utente SMTP
@@ -1035,13 +1035,13 @@ file_view_rendered=Visualizza Renderizzato
file_view_raw=Vedi originale
file_permalink=Permalink
file_too_large=Il file è troppo grande per essere visualizzato.
-bidi_bad_header=`Questo file contiene caratteri Unicode Bidirezionali inattesi!`
-bidi_bad_description=`Questo file contiene caratteri inaspettati Bidirezionali Unicode che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.`
-bidi_bad_description_escaped=`Questo file contiene caratteri Unicode bidirezionali inattesi. I caratteri unicode nascosti sono sfuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.`
-unicode_header=`Questo file contiene caratteri Unicode nascosti!`
-unicode_description=`Questo file contiene caratteri Unicode nascosti che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.`
-unicode_description_escaped=`Questo file contiene caratteri Unicode nascosti. I caratteri unicode nascosti sono fuggiti qui sotto. Usa il pulsante Unescape per mostrare come render.`
-line_unicode=`Questa riga ha caratteri unicode nascosti`
+invisible_runes_header=`Questo file contiene caratteri Unicode invisibili!`
+invisible_runes_description=`Questo file contiene caratteri Unicode invisibili che possono essere elaborati in modo diverso da quello che appare di seguito. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per rivelare caratteri nascosti.`
+ambiguous_runes_header=`Questo file contiene caratteri Unicode ambigui!`
+ambiguous_runes_description=`Questo file contiene caratteri Unicode ambigui che possono essere confusi con altri nella tua localizzazione attuale. Se il tuo caso di utilizzo è intenzionale e legittimo, puoi tranquillamente ignorare questo avviso. Usa il pulsante Escape per evidenziare questi caratteri.`
+invisible_runes_line=`Questa riga ha caratteri unicode invisibili`
+ambiguous_runes_line=`Questa riga ha caratteri unicode ambigui`
+ambiguous_character=`%[1]c [U+%04[1]X] è confondibile con %[2]c [U+%04[2]X]`
escape_control_characters=Fuga
unescape_control_characters=Unescape
@@ -1062,6 +1062,7 @@ normal_view=Vista normale
line=riga
lines=righe
+editor.add_file=Aggiungi file
editor.new_file=Nuovo file
editor.upload_file=Carica File
editor.edit_file=Modifica File
@@ -1267,6 +1268,8 @@ issues.filter_milestone=Traguardo
issues.filter_milestone_no_select=Tutte le pietre miliari
issues.filter_assignee=Assegnatario
issues.filter_assginee_no_select=Tutte le assegnazioni
+issues.filter_poster=Autore
+issues.filter_poster_no_select=Tutti gli autori
issues.filter_type=Tipo
issues.filter_type.all_issues=Tutti i problemi
issues.filter_type.assigned_to_you=Assegnati a te
@@ -2795,16 +2798,19 @@ config.queue_length=Lunghezza della coda
config.deliver_timeout=Tempo Limite di Consegna
config.skip_tls_verify=Salta autenticazione TLS
-config.mailer_config=Configurazione Mailer SMTP
+config.mailer_config=Configurazione Mailer
config.mailer_enabled=Attivo
-config.mailer_disable_helo=Disattiva HELO
+config.mailer_enable_helo=Abilita HELO
config.mailer_name=Nome
-config.mailer_host=Host
+config.mailer_protocol=Protocollo
+config.mailer_smtp_addr=Indirizzo SMTP
+config.mailer_smtp_port=Porta SMTP
config.mailer_user=Utente
config.mailer_use_sendmail=Utilizza Sendmail
config.mailer_sendmail_path=Percorso Sendmail
config.mailer_sendmail_args=Argomenti aggiuntivi per Sendmail
config.mailer_sendmail_timeout=Timeout Sendmail
+config.mailer_use_dummy=Dummy
config.test_email_placeholder=Email (es. test@example.com)
config.send_test_mail=Invia email di prova
config.test_mail_failed=Impossibile inviare mail di prova a '%s': %v
@@ -2889,6 +2895,7 @@ monitor.queue.nopool.title=Nessun pool di Workers
monitor.queue.nopool.desc=Questa coda racchiude altre code al suo interno e non ha un proprio pool.
monitor.queue.wrapped.desc=Una coda a capo avvolge una coda iniziale lenta, le richieste in coda di buffering in un canale. Non ha un pool di lavoratori stesso.
monitor.queue.persistable-channel.desc=Un canale persistibile avvolge due code, una coda di canale che ha un proprio pool di operatori e una coda di livello per le richieste persistenti dagli arresti precedenti. Non ha un pool di operai.
+monitor.queue.flush=Flush worker
monitor.queue.pool.timeout=Timeout
monitor.queue.pool.addworkers.title=Aggiungi Workers
monitor.queue.pool.addworkers.submit=Aggiungi Workers
@@ -3107,6 +3114,9 @@ npm.dependencies.development=Dipendenze Di Sviluppo
npm.dependencies.peer=Dipendenze Peer
npm.dependencies.optional=Dipendenze Opzionali
npm.details.tag=Tag
+pub.install=Per installare il pacchetto utilizzando NuGet, eseguire il seguente comando:
+pub.documentation=Per ulteriori informazioni sul registro Pub, consultare la documentazione .
+pub.details.repository_site=Sito Repository
pypi.requires=Richiede Python
pypi.install=Per installare il pacchetto usando pip, eseguire il seguente comando:
pypi.documentation=Per ulteriori informazioni sul registro PyPI, consultare la documentazione .
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index b91f3c87e73b..efb41ddd84c4 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -9,7 +9,6 @@ sign_out=サインアウト
sign_up=登録
link_account=アカウント連携
register=登録
-website=Webサイト
version=バージョン
powered_by=Powered by %s
page=ページ
@@ -179,7 +178,8 @@ log_root_path_helper=ログファイルがこのディレクトリに書き込
optional_title=オプション設定
email_title=メール設定
-smtp_host=SMTPホスト
+smtp_addr=SMTPホスト
+smtp_port=SMTPポート
smtp_from=メール送信者
smtp_from_helper=Giteaが使用するメールアドレス。 メールアドレスのみ、または、 "名前" の形式で入力してください。
mailer_user=SMTPユーザー名
@@ -1035,13 +1035,6 @@ file_view_rendered=レンダリング表示
file_view_raw=Rawデータを見る
file_permalink=パーマリンク
file_too_large=このファイルは大きすぎるため、表示できません。
-bidi_bad_header=`このファイルには予期しない双方向Unicode文字が含まれています!`
-bidi_bad_description=`このファイルには予期しない双方向Unicode文字が含まれており、下に見えているものとは異なる処理が行われる可能性があります。 あなたのユースケースが意図的かつ正当な場合はこの警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。`
-bidi_bad_description_escaped=`このファイルには予期しない双方向Unicode文字が含まれています。 下の表示では、不可視Unicode文字はエスケープされています。 どのようにレンダリングされるかを表示するにはエスケープ解除ボタンを使用します。`
-unicode_header=`このファイルには不可視Unicode文字が含まれています!`
-unicode_description=`このファイルには不可視Unicode文字が含まれており、下に見えているものとは異なる処理が行われる可能性があります。 あなたのユースケースが意図的かつ正当な場合はこの警告を無視して構いません。 不可視文字を表示するにはエスケープボタンを使用します。`
-unicode_description_escaped=`このファイルには不可視Unicode文字が含まれています。 下の表示では、不可視Unicode文字はエスケープされています。 どのようにレンダリングされるかを表示するにはエスケープ解除ボタンを使用します。`
-line_unicode=`この行には不可視Unicode文字があります`
escape_control_characters=エスケープ
unescape_control_characters=エスケープ解除
@@ -1062,6 +1055,7 @@ normal_view=通常表示
line=行
lines=行
+editor.add_file=ファイル追加
editor.new_file=新規ファイル
editor.upload_file=ファイルをアップロード
editor.edit_file=ファイルを編集
@@ -1267,6 +1261,8 @@ issues.filter_milestone=マイルストーン
issues.filter_milestone_no_select=すべてのマイルストーン
issues.filter_assignee=担当者
issues.filter_assginee_no_select=すべての担当者
+issues.filter_poster=作成者
+issues.filter_poster_no_select=すべての作成者
issues.filter_type=タイプ
issues.filter_type.all_issues=すべてのイシュー
issues.filter_type.assigned_to_you=自分が担当
@@ -2795,16 +2791,19 @@ config.queue_length=キューの長さ
config.deliver_timeout=送信タイムアウト
config.skip_tls_verify=TLS検証を省略
-config.mailer_config=SMTPメーラーの設定
+config.mailer_config=メーラー設定
config.mailer_enabled=有効
-config.mailer_disable_helo=HELOコマンド無効
+config.mailer_enable_helo=HELO有効
config.mailer_name=名称
-config.mailer_host=ホスト
+config.mailer_protocol=プロトコル
+config.mailer_smtp_addr=SMTPアドレス
+config.mailer_smtp_port=SMTPポート
config.mailer_user=ユーザー
config.mailer_use_sendmail=Sendmailを使う
config.mailer_sendmail_path=Sendmailのパス
config.mailer_sendmail_args=Sendmailの追加引数
config.mailer_sendmail_timeout=Sendmail のタイムアウト
+config.mailer_use_dummy=Dummy
config.test_email_placeholder=Email (例 test@example.com)
config.send_test_mail=テストメールを送信
config.test_mail_failed='%s' へのテストメール送信に失敗しました: %v
@@ -3107,6 +3106,10 @@ npm.dependencies.development=開発用依存関係
npm.dependencies.peer=Peer依存関係
npm.dependencies.optional=オプションの依存関係
npm.details.tag=タグ
+pub.install=Dart を使用してパッケージをインストールするには、次のコマンドを実行します:
+pub.documentation=Pub レジストリの詳細については、ドキュメント を参照してください。
+pub.details.repository_site=リポジトリサイト
+pub.details.documentation_site=ドキュメントサイト
pypi.requires=必要なPython
pypi.install=pip を使用してパッケージをインストールするには、次のコマンドを実行します:
pypi.documentation=PyPI レジストリの詳細については、ドキュメント を参照してください。
diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini
index ab8908e531f3..d4917f861ab4 100644
--- a/options/locale/locale_ko-KR.ini
+++ b/options/locale/locale_ko-KR.ini
@@ -8,7 +8,6 @@ sign_out=로그아웃
sign_up=가입하기
link_account=계정 연결
register=가입하기
-website=웹 사이트
version=버전
powered_by=%s 제공
page=페이지
@@ -126,7 +125,6 @@ log_root_path_helper=로그파일은 이 디렉토리에 저장됩니다.
optional_title=추가설정
email_title=이메일 설정
-smtp_host=SMTP 호스트
smtp_from=이메일 발신인
smtp_from_helper=Gitea 가 사용할 이메일 주소. 이메일 주소 또는 "이름" 형식으로 입력하세요.
mailer_user=SMTP 사용자이름
@@ -1450,11 +1448,8 @@ config.queue_length=큐 길이
config.deliver_timeout=시간 제한 사용
config.skip_tls_verify=TLS 검증 건너뛰기
-config.mailer_config=SMTP 메일러 설정
config.mailer_enabled=활성화됨
-config.mailer_disable_helo=HELO 비활성화
config.mailer_name=이름
-config.mailer_host=호스트
config.mailer_user=사용자
config.mailer_use_sendmail=Sendmail 사용
config.mailer_sendmail_path=Sendmail 경로
diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini
index 5cecb321dc4c..b82675762035 100644
--- a/options/locale/locale_lv-LV.ini
+++ b/options/locale/locale_lv-LV.ini
@@ -9,7 +9,6 @@ sign_out=Izrakstīties
sign_up=Reģistrēties
link_account=Saistītie konti
register=Reģistrēties
-website=Mājas lapa
version=Versija
powered_by=Darbina %s
page=Lapa
@@ -179,7 +178,8 @@ log_root_path_helper=Žurnalizēšanas faili tiks rakstīti šajā direktorijā.
optional_title=Neobligātie iestatījumi
email_title=E-pastu iestatījumi
-smtp_host=SMTP resursdators
+smtp_addr=SMTP resursdators
+smtp_port=SMTP ports
smtp_from=Nosūtīt e-pastu kā
smtp_from_helper=E-pasta adrese, ko Gitea izmantos. Ievadiet tika e-pasta adrese vai izmantojiet "Vārds" formātu.
mailer_user=SMTP lietotāja vārds
@@ -799,6 +799,7 @@ email_notifications.enable=Iespējot e-pasta paziņojumus
email_notifications.onmention=Tikai, ja esmu pieminēts
email_notifications.disable=Nesūtīt paziņojumus
email_notifications.submit=Saglabāt sūtīšanas iestatījumus
+email_notifications.andyourown=Iekļaut savus paziņojumus
visibility=Lietotāja redzamība
visibility.public=Publisks
@@ -861,7 +862,9 @@ default_branch=Noklusējuma atzars
default_branch_helper=Noklusētais atzars nosaka pamata atzaru uz kuru tiks veidoti izmaiņu pieprasījumi un koda revīziju iesūtīšana.
mirror_prune=Izmest
mirror_prune_desc=Izdzēst visas ārējās atsauces, kas ārējā repozitorijā vairs neeksistē
+mirror_interval=Spoguļošanas intervāls (derīgas laika vienības ir 'h', 'm', 's'). Norādiet 0, lai atslēgtu periodisku spoguļošanu. (Minimālais intervāls: %s)
mirror_interval_invalid=Nekorekts spoguļošanas intervāls.
+mirror_sync_on_commit=Sinhronizēt, kad revīzijas tiek iesūtītas
mirror_address=Spoguļa adrese
mirror_address_desc=Pieslēgšanās rekvizītus norādiet autorizācijas sadaļā.
mirror_address_url_invalid=Norādītais URL nav korekts. Norādiet visas URL daļas korekti.
@@ -930,6 +933,7 @@ form.name_pattern_not_allowed=Repozitorija nosaukums '%s' nav atļauts.
need_auth=Autorizācija
migrate_options=Migrācijas opcijas
migrate_service=Migrācijas serviss
+migrate_options_mirror_helper=Šis repozitorijs būs spogulis
migrate_options_lfs=Migrēt LFS failus
migrate_options_lfs_endpoint.label=LFS galapunkts
migrate_options_lfs_endpoint.description=Migrācija mēģinās izmantot attālināto URL, lai noteiktu LFS serveri . Var norādīt arī citu galapunktu, ja repozitorija LFS dati ir izvietoti citā vietā.
@@ -1031,13 +1035,6 @@ file_view_rendered=Skatīt rezultātu
file_view_raw=Rādīt neapstrādātu
file_permalink=Patstāvīgā saite
file_too_large=Šis fails ir par lielu, lai to parādītu.
-bidi_bad_header=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus!`
-bidi_bad_description=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus, kas var mainīt kā saturs tiek attēlots. Ja tie ir izmantoti ar pamatotu nodumu, tad varat ignorēt šo brīdinājumu. Izmantojiet Kodēt pogu, lai parādītu šos neredzamos simbolus.`
-bidi_bad_description_escaped=`Šis fails satur neparedzētus virzienmaiņas unikoda simbolus. Neredzamie unikoda simboli ir kodēti, lai būtu redzami. Izmantojiet Atkodēt pogu, lai redzētu kā tie tiek attēloti.`
-unicode_header=`Šis fails satur neredzamus unikoda simbolus!`
-unicode_description=`Šis fails satur neredzamus unikoda simbolus, kas var mainīt kā saturs tiek attēlots. Ja tie ir izmantoti ar pamatotu nodumu, tad varat ignorēt šo brīdinājumu. Izmantojiet Kodēt pogu, lai parādītu šos neredzamos simbolus.`
-unicode_description_escaped=`Šis fails satur neredzamus unikoda simbolus. Neredzamie unikoda simboli ir kodēti, lai būtu redzami. Izmantojiet Atkodēt pogu, lai redzētu kā tie tiek attēloti.`
-line_unicode=`Šajā līnijā ir paslēpti unikoda simboli`
escape_control_characters=Kodēt
unescape_control_characters=Atkodēt
@@ -1058,6 +1055,7 @@ normal_view=Parastais skats
line=rinda
lines=rindas
+editor.add_file=Pievienot
editor.new_file=Jauna datne
editor.upload_file=Augšupielādēt failu
editor.edit_file=Labot failu
@@ -1300,6 +1298,7 @@ issues.previous=Iepriekšējā
issues.next=Nākamā
issues.open_title=Atvērta
issues.closed_title=Slēgta
+issues.draft_title=Melnraksts
issues.num_comments=%d komentāri
issues.commented_at=` komentēja %s `
issues.delete_comment_confirm=Vai patiešām vēlaties dzēst šo komentāru?
@@ -1416,6 +1415,7 @@ issues.due_date_form_remove=Noņemt
issues.due_date_not_writer=Jums ir nepieciešamas rakstīšanas tiesības uz šo repozitoriju, lai mainītu izpildes termiņu.
issues.due_date_not_set=Izpildes termiņš nav uzstādīts.
issues.due_date_added=pievienoja izpildes termiņu %s %s
+issues.due_date_modified=mainīja termiņa datumu no %[2]s uz %[1]s %[3]s
issues.due_date_remove=noņēma izpildes termiņu %s %s
issues.due_date_overdue=Nokavēts
issues.due_date_invalid=Datums līdz nav korekts. Izmantojiet formātu 'gggg-mm-dd'.
@@ -1527,6 +1527,8 @@ pulls.remove_prefix=Noņemt %s prefiksu
pulls.data_broken=Izmaiņu pieprasījums ir bojāts, jo dzēsta informācija no atdalītā repozitorija.
pulls.files_conflicted=Šīs izmaiņu pieprasījuma izmaiņas konfliktē ar mērķa atzaru.
pulls.is_checking=Notiek konfliktu pārbaude, mirkli uzgaidiet un atjaunojiet lapu.
+pulls.is_ancestor=Atzars jau ir pilnībā iekļauts mērķā atzarā. Nav izmaiņu, ko sapludināt.
+pulls.is_empty=Mērķa atzars jau satur šī atzara izmaiņas. Šī revīzija būs tukša.
pulls.required_status_check_failed=Dažas no pārbaudēm nebija veiksmīgas.
pulls.required_status_check_missing=Trūkst dažu obligāto pārbaužu.
pulls.required_status_check_administrator=Kā administrators Jūs varat sapludināt šo izmaiņu pieprasījumu.
@@ -1605,6 +1607,8 @@ pulls.auto_merge_canceled_schedule=Automātiskā sapludināšana šim izmaiņu p
pulls.auto_merge_newly_scheduled_comment=`ieplānoja automātisko sapludināšanu šim izmaiņu pieprasījumam, kad visas pārbaudes būs veiksmīgas %[1]s`
pulls.auto_merge_canceled_schedule_comment=`atcēla automātisko sapludināšanu šim izmaiņu pieprasījumam %[1]s`
+pulls.delete.title=Dzēst šo izmaiņu pieprasījumu?
+pulls.delete.text=Vai patiešām vēlaties dzēst šo izmaiņu pieprasījumu? (Neatgriezeniski tiks izdzēsts viss saturs. Apsveriet iespēju to aizvērt, ja vēlaties informāciju saglabāt vēsturei)
milestones.new=Jauns atskaites punkts
milestones.closed=Aizvērts %s
@@ -2527,6 +2531,8 @@ users.delete_account=Dzēst lietotāja kontu
users.cannot_delete_self=Nevar izdzēst sevi
users.still_own_repo=Lietotājam pieder repozitoriji, tos sākumā ir nepieciešams izdzēst vai mainīt to īpašnieku.
users.still_has_org=Šis lietotājs ir vienas vai vairāku organizāciju biedrs, lietotāju sākumā ir nepieciešams pamest šīs organizācijas vai viņu no tām ir jāizdzēš.
+users.purge=Attīrīt lietotu
+users.purge_help=Piespiedu dzēst lietotāju un visus tā repozitorijus, organizācijas un pakotnes. Arī visi lietotāja komentāri tiks dzēsti.
users.still_own_packages=Šim lietotājam pieder viena vai vairākas pakotnes. Tās nepieciešams izdzēst.
users.deletion_success=Lietotāja konts veiksmīgi izdzēsts.
users.reset_2fa=Noņemt 2FA
@@ -2783,16 +2789,19 @@ config.queue_length=Rindas garums
config.deliver_timeout=Piegādes noildze
config.skip_tls_verify=Izlaist TLS pārbaudi
-config.mailer_config=SMTP sūtītāja konfigurācija
+config.mailer_config=Pasta sūtītāja konfigurācija
config.mailer_enabled=Iespējota
-config.mailer_disable_helo=Atspējot HELO
+config.mailer_enable_helo=Iespējot HELO
config.mailer_name=Nosaukums
-config.mailer_host=Resursdators
+config.mailer_protocol=Protokols
+config.mailer_smtp_addr=SMTP adrese
+config.mailer_smtp_port=SMTP ports
config.mailer_user=Lietotājs
config.mailer_use_sendmail=Izmantot Sendmail
config.mailer_sendmail_path=Ceļš līdz sendmail programmai
config.mailer_sendmail_args=Papildus Sendmail komandrindas argumenti
config.mailer_sendmail_timeout=Sendmail noildze
+config.mailer_use_dummy=Tukšs
config.test_email_placeholder=E-pasts (piemēram, test@example.com)
config.send_test_mail=Nosūtīt pārbaudes e-pastu
config.test_mail_failed=Neizdevās nosūtīt pārbaudes e-pastu uz '%s': %v
@@ -3029,6 +3038,7 @@ title=Pakotnes
desc=Pārvaldīt repozitorija pakotnes.
empty=Pašlaik šeit nav nevienas pakotnes.
empty.documentation=Papildus informācija par pakotņu reģistru pieejama dokumentācijā .
+empty.repo=Neparādās augšupielādēta pakotne? Apmeklējiet pakotņu iestatījumus , lai sasaistītu ar repozitoriju.
filter.type=Veids
filter.type.all=Visas
filter.no_result=Pēc norādītajiem kritērijiem nekas netika atrasts.
@@ -3094,6 +3104,10 @@ npm.dependencies.development=Izstrādes atkarības
npm.dependencies.peer=Netiešās atkarības
npm.dependencies.optional=Neobligātās atkarības
npm.details.tag=Tags
+pub.install=Lai instalētu Dart pakotni, izpildiet sekojošu komandu:
+pub.documentation=Papildus informācija par Pub reģistru pieejama dokumentācijā .
+pub.details.repository_site=Repozitorija izmērs
+pub.details.documentation_site=Dokumentācijas lapa
pypi.requires=Nepieciešams Python
pypi.install=Lai instalētu pip pakotni, izpildiet sekojošu komandu:
pypi.documentation=Papildus informācija par PyPI reģistru pieejama dokumentācijā .
diff --git a/options/locale/locale_ml-IN.ini b/options/locale/locale_ml-IN.ini
index 27e4f1127938..7ee595bf4fce 100644
--- a/options/locale/locale_ml-IN.ini
+++ b/options/locale/locale_ml-IN.ini
@@ -8,7 +8,6 @@ sign_out=പുറത്തുകടക്കുക
sign_up=രജിസ്റ്റർ
link_account=അക്കൌണ്ട് ബന്ധിപ്പിയ്ക്കുക
register=രജിസ്റ്റർ
-website=വെബ് സൈറ്റ്
version=പതിപ്പ്
page=പേജ്
template=ടെംപ്ലേറ്റ്
@@ -112,7 +111,6 @@ log_root_path_helper=ലോഗ് ഫയലുകൾ ഈ ഡയറക്ടറ
optional_title=ഐച്ഛികമായ ക്രമീകരണങ്ങൾ
email_title=ഇമെയിൽ ക്രമീകരണങ്ങൾ
-smtp_host=SMTP ഹോസ്റ്റ്
smtp_from=ഈ വിലാസത്തില് ഇമെയിൽ അയയ്ക്കുക
smtp_from_helper=ഗിറ്റീ ഉപയോഗിയ്ക്കുന്ന ഇമെയില് വിലാസം. ഒരു സാധാ ഇമെയിൽ വിലാസം നൽകുക അല്ലെങ്കിൽ "പേര്" എന്ന ഘടന ഉപയോഗിക്കുക.
mailer_user=SMTP ഉപയോക്തൃനാമം
diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini
index fcc048b3c1c5..5b18185fefd5 100644
--- a/options/locale/locale_nl-NL.ini
+++ b/options/locale/locale_nl-NL.ini
@@ -9,7 +9,6 @@ sign_out=Uitloggen
sign_up=Registreren
link_account=Account Koppelen
register=Registreren
-website=Website
version=Versie
powered_by=Powered by %s
page=Pagina
@@ -179,7 +178,8 @@ log_root_path_helper=Logboekbestanden worden geschreven naar deze map.
optional_title=Optionele instellingen
email_title=E-mail instellingen
-smtp_host=SMTP host
+smtp_addr=SMTP Host
+smtp_port=SMTP Poort
smtp_from=E-mails versturen als
smtp_from_helper=E-mailadres dat Gitea gaat gebruiken. Voer een gewoon e-mailadres in of gebruik de "Naam" -indeling.
mailer_user=SMTP gebruikersnaam
@@ -1035,13 +1035,13 @@ file_view_rendered=Weergave weergeven
file_view_raw=Weergave ruw bestand
file_permalink=Permalink
file_too_large=Dit bestand is te groot om te tonen.
-bidi_bad_header=`Dit bestand bevat onverwachte Bidirectionele Unicode karakters!`
-bidi_bad_description=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.`
-bidi_bad_description_escaped=`Dit bestand bevat onverwachte Bidirectionele Unicode-tekens. Verborgen unicode tekens worden hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.`
-unicode_header=`Dit bestand bevat verborgen Unicode karakters!`
-unicode_description=`Dit bestand bevat verborgen Unicode-tekens die anders verwerkt kunnen worden dan hieronder het geval is. Als uw gebruik ervan opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.`
-unicode_description_escaped=`Dit bestand bevat verborgen Unicode-tekens. Verborgen unicode tekens zijn hieronder ge-escaped. Gebruik de knop Onescape om te laten zien hoe ze renderen.`
-line_unicode=`Deze regel bevat verborgen Unicode karakters`
+invisible_runes_header=`Dit bestand bevat onzichtbare Unicode-karakters!`
+invisible_runes_description=`Dit bestand bevat onzichtbare Unicode karakters die mogelijk anders verwerkt worden dan wat hieronder staat. Als uw gebruik opzettelijk en legitiem is, kunt u deze waarschuwing veilig negeren. Gebruik de Escape knop om verborgen karakters te onthullen.`
+ambiguous_runes_header=`Dit bestand bevat dubbelzinnige Unicode karakters!`
+ambiguous_runes_description=`Dit bestand bevat dubbelzinnige Unicode karakters die verward kunnen worden met andere karakters in uw huidige taal. Als je het opzettelijk en legitiem gebruikt, kun je deze waarschuwing veilig negeren. Gebruik de Escape knop om deze karakters te markeren.`
+invisible_runes_line=`Deze lijn heeft onzichtbare unicode karakters`
+ambiguous_runes_line=`Deze lijn heeft dubbelzinnige unicode karakters`
+ambiguous_character=`%[1]c [U+%04[1]X] is verwarrend met %[2]c [U+%04[2]X]`
escape_control_characters=Escape
unescape_control_characters=Onescape
@@ -1062,6 +1062,7 @@ normal_view=Normale weergave
line=regel
lines=regels
+editor.add_file=Bestand toevoegen
editor.new_file=Nieuw bestand
editor.upload_file=Upload bestand
editor.edit_file=Bewerk bestand
@@ -1242,6 +1243,7 @@ issues.add_label=voegde het %s label %s toe
issues.add_labels=voegde de %s labels %s toe
issues.remove_label=verwijderde het %s label %s
issues.remove_labels=verwijderde de %s labels %s
+issues.add_remove_labels=voegde de %s toe en verwijderde de %s labels %s
issues.add_milestone_at=`heeft dit %[2]s aan de mijlpaal %[1]s toegevoegd`
issues.add_project_at=`heeft dit toegevoegd aan het %s project %s`
issues.change_milestone_at='mijlpaal bewerkt van %s %s %s'
@@ -1255,6 +1257,9 @@ issues.add_assignee_at=`was toegekend door %s %s`
issues.remove_assignee_at=`is niet toegewezen door %s %s`
issues.remove_self_assignment=`heeft %s zijn/haar toewijzing verwijderd`
issues.change_title_at='titel aangepast van %s naar %s %s'
+issues.change_ref_at=`wijzig referentie van %s naar %s %s`
+issues.remove_ref_at=`heeft referentie %s verwijderd %s`
+issues.add_ref_at=`heeft referentie %s toegevoegd %s`
issues.delete_branch_at=`heeft %[2]s de branch %[1]s verwijderd.`
issues.filter_label=Label
issues.filter_label_exclude=`Gebruik alt
+ klik/voer
in om labels uit te sluiten
@@ -1263,11 +1268,14 @@ issues.filter_milestone=Mijlpaal
issues.filter_milestone_no_select=Alle mijlpalen
issues.filter_assignee=Aangewezene
issues.filter_assginee_no_select=Alle toegewezen personen
+issues.filter_poster=Auteur
+issues.filter_poster_no_select=Alle auteurs
issues.filter_type=Type
issues.filter_type.all_issues=Alle kwesties
issues.filter_type.assigned_to_you=Aan jou toegewezen
issues.filter_type.created_by_you=Aangemaakt door jou
issues.filter_type.mentioning_you=Vermelden jou
+issues.filter_type.review_requested=Review aangevraagd
issues.filter_sort=Sorteer
issues.filter_sort.latest=Nieuwste
issues.filter_sort.oldest=Oudste
@@ -1281,6 +1289,7 @@ issues.filter_sort.moststars=Meeste sterren
issues.filter_sort.feweststars=Minste sterren
issues.filter_sort.mostforks=Meeste forks
issues.filter_sort.fewestforks=Minste forks
+issues.keyword_search_unavailable=Zoeken op trefwoord is momenteel niet beschikbaar. Neem contact op met de websitebeheerder.
issues.action_open=Open
issues.action_close=Sluit
issues.action_label=Label
@@ -1289,19 +1298,28 @@ issues.action_milestone_no_select=Geen mijlpaal
issues.action_assignee=Toegewezene
issues.action_assignee_no_select=Geen verantwoordelijke
issues.opened_by=%[1]s geopend door %[3]s
+pulls.merged_by=door %[3]s was samengevoegd %[1]s
+pulls.merged_by_fake=bij %[2]s is %[1]s samengevoegd
+issues.closed_by=door %[3]s was gesloten %[1]s
+issues.opened_by_fake=%[1]s geopend door %[2]s
+issues.closed_by_fake=door %[2]s was gesloten %[1]s
issues.previous=Vorige
issues.next=Volgende
issues.open_title=Open
issues.closed_title=Gesloten
+issues.draft_title=Concept
issues.num_comments=%d opmerkingen
issues.commented_at=`reageerde %s `
issues.delete_comment_confirm=Weet u zeker dat u deze reactie wilt verwijderen?
issues.context.copy_link=Link kopiëren
issues.context.quote_reply=Citeer antwoord
+issues.context.reference_issue=Verwijs in nieuw issue
issues.context.edit=Bewerken
issues.context.delete=Verwijder
issues.no_content=Er is nog geen inhoud.
issues.close_issue=Sluit
+issues.pull_merged_at=`commit samengevoegd %[2]s
in %[3]s %[4]s`
+issues.manually_pull_merged_at=`commit handmatig samengevoegd %[2]s
in %[3]s %[4]s`
issues.close_comment_issue=Reageer en sluit
issues.reopen_issue=Heropen
issues.reopen_comment_issue=Heropen en geef commentaar
@@ -1323,6 +1341,8 @@ issues.re_request_review=Opnieuw aanvragen review
issues.is_stale=Er zijn wijzigingen aangebracht in deze PR sinds deze beoordeling
issues.remove_request_review=Verwijder beoordelingsverzoek
issues.remove_request_review_block=Kan beoordelingsverzoek niet verwijderen
+issues.dismiss_review=Beoordeling afwijzen
+issues.dismiss_review_warning=Bent u zeker dat u deze beoordeling wilt afwijzen?
issues.sign_in_require_desc=Log in om deel te nemen aan deze discussie.
issues.edit=Bewerken
issues.cancel=Annuleren
@@ -1366,13 +1386,21 @@ issues.lock.reason=Reden voor vergrendeling
issues.lock.title=Vergrendel gesprek over dit probleem.
issues.unlock.title=Ontgrendel gesprek over dit probleem.
issues.comment_on_locked=Je kunt geen commentaar geven op een vergrendeld probleem.
+issues.delete=Verwijderen
+issues.delete.title=Deze issue verwijderen?
+issues.delete.text=Wilt u deze issue echt verwijderen? (Dit is permanent en verwijdert alle inhoud. Overweeg om deze issue te sluiten, als u liever deze als archief wilt bijhouden)
issues.tracker=Tijdregistratie
+issues.start_tracking_short=Start timer
issues.start_tracking=Start tijdregistratie
issues.start_tracking_history=`%s is begonnen`
issues.tracker_auto_close=Timer wordt automatisch gestopt wanneer dit probleem wordt gesloten
+issues.tracking_already_started=`Je houd al tijd bij voor een ander issue !`
+issues.stop_tracking=Stop timer
issues.stop_tracking_history=`gestopt met werken aan %s`
+issues.cancel_tracking=Weggooien
issues.cancel_tracking_history=`tijd bijhouden geannuleerd: %s`
issues.add_time=Tijd handmatig toevoegen
+issues.del_time=Verwijder deze tijdlog
issues.add_time_short=Timer toevoegen
issues.add_time_cancel=Annuleren
issues.add_time_history=`heeft besteedde tijd toegevoegd: %s`
@@ -1388,6 +1416,7 @@ issues.error_modifying_due_date=Deadline aanpassen mislukt.
issues.error_removing_due_date=Deadline verwijderen mislukt.
issues.push_commit_1=toegevoegd %d commit %s
issues.push_commits_n=toegevoegd %d commits %s
+issues.force_push_codes=`force-push %[1]s van %[2]s
naar %[4]s
%[6]s`
issues.due_date_form=jjjj-mm-dd
issues.due_date_form_add=Vervaldatum toevoegen
issues.due_date_form_edit=Bewerk
@@ -1395,16 +1424,20 @@ issues.due_date_form_remove=Verwijder
issues.due_date_not_writer=Je hebt schrijftoegang in deze repository nodig om de deadline van een kwestie aan te passen.
issues.due_date_not_set=Geen vervaldatum ingesteld.
issues.due_date_added=heeft %[2]s de deadline %[1]s toegevoegd
+issues.due_date_modified=de vervaldatum van %[2]s is gewijzigd naar %[1]s[3]s
issues.due_date_remove=heeft %[2]s de deadline %[1]s verwijderd
issues.due_date_overdue=Over tijd
issues.due_date_invalid=De deadline is ongeldig of buiten bereik. Gebruik het formaat 'jjjj-mm-dd'.
issues.dependency.title=Afhankelijkheden
+issues.dependency.issue_no_dependencies=Geen afhankelijkheden ingesteld.
+issues.dependency.pr_no_dependencies=Geen afhankelijkheden ingesteld.
issues.dependency.add=Voeg afhankelijkheid toe…
issues.dependency.cancel=Annuleer
issues.dependency.remove=Verwijder
issues.dependency.remove_info=Verwijder afhankelijkheid
issues.dependency.added_dependency=`voegde een nieuwe afhankelijkheid %s toe `
issues.dependency.removed_dependency=`verwijderde een afhankelijkheid %s`
+issues.dependency.pr_closing_blockedby=Het sluiten van deze pull-aanvraag is geblokkeerd door de volgende issues
issues.dependency.issue_closing_blockedby=Het sluiten van dit issue is geblokkeerd door de volgende problemen
issues.dependency.issue_close_blocks=Deze kwestie blokkeert het sluiten van de volgende kwesties
issues.dependency.pr_close_blocks=Deze pull-aanvraag blokkeert het sluiten van de volgende kwesties
@@ -1577,8 +1610,12 @@ pulls.auto_merge_newly_scheduled=De pull-verzoek was gepland om samen te voegen
pulls.auto_merge_has_pending_schedule=%[1]s heeft deze pull-verzoek automatisch samengevoegd wanneer alle checks succesvol zijn geweest %[2]s.
pulls.auto_merge_cancel_schedule=Automatisch samenvoegen annuleren
+pulls.auto_merge_not_scheduled=Deze pull-aanvraag is niet gepland om automatisch samen te voegen.
+pulls.auto_merge_canceled_schedule=De automatisch samenvoegen is geannuleerd voor deze pull-aanvraag.
+pulls.delete.title=Deze pull-verzoek verwijderen?
+pulls.delete.text=Weet je zeker dat je deze pull-verzoek wilt verwijderen? (Dit zal alle inhoud permanent verwijderen. Overweeg om het te sluiten als je het gearchiveerd wilt houden)
milestones.new=Nieuwe mijlpaal
milestones.closed=%s werd gesloten
@@ -1624,6 +1661,7 @@ signing.wont_sign.commitssigned=De samenvoeging wordt niet ondertekend omdat all
signing.wont_sign.approved=De samenvoeging wordt niet ondertekend omdat de PR niet is goedgekeurd
signing.wont_sign.not_signed_in=U bent niet ingelogd
+ext_wiki=Toegang tot Externe Wiki
ext_wiki.desc=Koppelen aan een externe wiki.
wiki=Wiki
@@ -1648,6 +1686,7 @@ wiki.page_already_exists=Er bestaat al een wiki-pagina met deze naam.
wiki.reserved_page=De wiki-paginanaam '%s' is gereserveerd.
wiki.pages=Pagina’s
wiki.last_updated=Laatst bijgewerkt: %s
+wiki.page_name_desc=Voer een naam in voor deze Wiki pagina. Sommige speciale namen zijn: 'Home', '_Sidebar' en '_Footer'.
activity=Activiteit
activity.period.filter_label=Periode:
@@ -1679,6 +1718,7 @@ activity.closed_issues_count_1=Gesloten problemen
activity.closed_issues_count_n=Gesloten problemen
activity.title.issues_1=%d Probleem
activity.title.issues_n=%d Problemen
+activity.title.issues_closed_from=%s gesloten van %s
activity.title.issues_created_by=%s gemaakt door %s
activity.closed_issue_label=Gesloten
activity.new_issues_count_1=Nieuw probleem
@@ -1716,7 +1756,11 @@ activity.git_stats_deletion_n=%d verwijderingen
search=Zoek
search.search_repo=Zoek repository
+search.fuzzy=Vergelijkbaar
+search.match=Overeenkomst
search.results=Zoek resultaat voor "%s" in %s
+search.code_no_results=Geen broncode gevonden die aan uw zoekterm voldoet.
+search.code_search_unavailable=Er is momenteel geen code zoekfunctie beschikbaar. Neem contact op met uw sitebeheerder.
settings=Instellingen
settings.desc=In de instellingen kan je de instellingen van de repository aanpassen
@@ -1731,14 +1775,18 @@ settings.hooks=Webhooks
settings.githooks=Git-hooks
settings.basic_settings=Basis instellingen
settings.mirror_settings=Kopie Settings
+settings.mirror_settings.mirrored_repository=Gespiegelde repository
settings.mirror_settings.direction=Richting
settings.mirror_settings.direction.pull=Pull
settings.mirror_settings.direction.push=Push
+settings.mirror_settings.last_update=Laatst bijgewerkt
settings.mirror_settings.push_mirror.none=Geen spiegels geconfigureerd
+settings.mirror_settings.push_mirror.add=Voeg Push Mirror toe
settings.sync_mirror=Synchroniseer
settings.mirror_sync_in_progress=Mirror-synchronisatie is momenteel bezig - kom later terug.
settings.site=Website
settings.update_settings=Instellingen bewerken
+settings.branches.update_default_branch=Standaard branch bijwerken
settings.advanced_settings=Geavanceerde opties
settings.wiki_desc=Repository-wiki inschakelen
settings.use_internal_wiki=Ingebouwde wiki gebruiken
@@ -1757,6 +1805,8 @@ settings.tracker_url_format_error=Het URL-formaat van de externe wiki is geen ge
settings.tracker_issue_style=Nummerformaat van de externe kwestie-tracker
settings.tracker_issue_style.numeric=Nummeriek
settings.tracker_issue_style.alphanumeric=Alfanummeriek
+settings.tracker_issue_style.regexp=Reguliere expressie
+settings.tracker_issue_style.regexp_pattern=Reguliere expressie patroon
settings.tracker_url_format_desc=Gebruik de aanduidingen {user}
, {repo}
en {index}
voor de gebruikersnaam, repositorynaam en kwestie-index.
settings.enable_timetracker=Tijdregistratie inschakelen
settings.allow_only_contributors_to_track_time=Sta alleen bijdragers toe tijdregistratie te gebruiken
@@ -2603,16 +2653,15 @@ config.queue_length=Lengte van wachtrij
config.deliver_timeout=Bezorging verlooptijd
config.skip_tls_verify=TLS-verificatie overslaan
-config.mailer_config=SMTP Mailerconfiguatie
config.mailer_enabled=Ingeschakeld
-config.mailer_disable_helo=Schakel HELO uit
config.mailer_name=Naam
-config.mailer_host=Host
+config.mailer_smtp_port=SMTP Poort
config.mailer_user=Gebruiker
config.mailer_use_sendmail=Gebruik Sendmail
config.mailer_sendmail_path=Sendmail pad
config.mailer_sendmail_args=Extra argumenten voor Sendmail
config.mailer_sendmail_timeout=Sendmail time-out
+config.mailer_use_dummy=Dummy
config.test_email_placeholder=E-mailadres (bijv. test@example.com)
config.send_test_mail=Test e-mail verzenden
config.test_mail_failed=Verzenden van een testmail naar '%s' is mislukt: %v
@@ -2689,6 +2738,7 @@ monitor.queue.review=Configuratie herzien
monitor.queue.review_add=Beoordeel/Voeg workers toe
monitor.queue.configuration=Initiële configuratie
monitor.queue.nopool.title=Geen Worker-pool
+monitor.queue.flush=Spoel werker
monitor.queue.pool.timeout=Time-out
monitor.queue.pool.addworkers.title=Voeg workers toe
monitor.queue.pool.addworkers.submit=Voeg workers toe
diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini
index 75c3d6287c3d..840f69d9308f 100644
--- a/options/locale/locale_pl-PL.ini
+++ b/options/locale/locale_pl-PL.ini
@@ -8,7 +8,6 @@ sign_out=Wyloguj
sign_up=Zarejestruj
link_account=Powiąż konto
register=Zarejestruj się
-website=Strona
version=Wersja
powered_by=Wspierane przez %s
page=Strona
@@ -177,7 +176,6 @@ log_root_path_helper=Pliki logów będą zapisywane w tym katalogu.
optional_title=Ustawienia opcjonalne
email_title=Ustawienia e-mail
-smtp_host=Serwer SMTP
smtp_from=Wyślij e-mail jako
smtp_from_helper=Adres e-mail, z którego Gitea będzie korzystać. Wpisz prosty adres e-mail, lub użyj formatu "Nazwa" .
mailer_user=Nazwa użytkownika SMTP
@@ -2494,11 +2492,8 @@ config.queue_length=Długość kolejki
config.deliver_timeout=Limit czasu doręczenia
config.skip_tls_verify=Pomiń weryfikację TLS
-config.mailer_config=Konfiguracja dostawcy SMTP
config.mailer_enabled=Włączona
-config.mailer_disable_helo=Wyłącz HELO
config.mailer_name=Nazwa
-config.mailer_host=Serwer
config.mailer_user=Użytkownik
config.mailer_use_sendmail=Używaj Sendmail
config.mailer_sendmail_path=Ścieżka Sendmail
diff --git a/options/locale/locale_pt-BR.ini b/options/locale/locale_pt-BR.ini
index 99d8fb2db18a..b5c81702dc70 100644
--- a/options/locale/locale_pt-BR.ini
+++ b/options/locale/locale_pt-BR.ini
@@ -9,7 +9,6 @@ sign_out=Sair
sign_up=Cadastrar
link_account=Vincular conta
register=Cadastrar
-website=Site
version=Versão
powered_by=Desenvolvido por %s
page=Página
@@ -179,7 +178,8 @@ log_root_path_helper=Arquivos de log serão gravados neste diretório.
optional_title=Configurações opcionais
email_title=Configurações de e-mail
-smtp_host=Host SMTP
+smtp_addr=Host SMTP
+smtp_port=Porta SMTP
smtp_from=Enviar e-mail como
smtp_from_helper=Endereço de e-mail que o Gitea irá usar. Digite um endereço de e-mail simples ou use o formato "Nome" .
mailer_user=Nome de usuário do SMTP
@@ -799,6 +799,7 @@ email_notifications.enable=Habilitar notificações de e-mail
email_notifications.onmention=Somente e-mail com menção
email_notifications.disable=Desabilitar notificações de e-mail
email_notifications.submit=Atualizar preferências de e-mail
+email_notifications.andyourown=E Suas Próprias Notificações
visibility=Visibilidade do usuário
visibility.public=Pública
@@ -1034,13 +1035,6 @@ file_view_rendered=Ver Renderizado
file_view_raw=Ver original
file_permalink=Link permanente
file_too_large=O arquivo é muito grande para ser mostrado.
-bidi_bad_header=`Este arquivo contém caracteres Unicode Bidirecionais inesperados!`
-bidi_bad_description=`Este arquivo contém caracteres Unicode bidirecionais inesperados que podem ser processados de forma diferente do que aparece abaixo. Se seu caso de uso for intencional e legítimo, você pode ignorar com segurança esse aviso. Use o botão Escapar para revelar caracteres ocultos.`
-bidi_bad_description_escaped=`Este arquivo contém caracteres Unicode Bidirecionais inesperados. Caracteres unicode ocultos estão escapados abaixo. Use o botão Desescapar para mostrar como eles são mostrados.`
-unicode_header=`Este arquivo contém caracteres Unicode ocultos!`
-unicode_description=`Este arquivo contém caracteres Unicode ocultos que podem ser processados de forma diferente do que aparece abaixo. Se seu caso de uso for intencional e legítimo, você pode ignorar com segurança esse aviso. Use o botão Escapar para revelar caracteres ocultos.`
-unicode_description_escaped=`Este arquivo contém caracteres Unicode ocultos. Caracteres unicode ocultos estão escapados abaixo. Utilize o botão Desescapar para mostrar como eles são mostrados.`
-line_unicode=`Esta linha possui caracteres unicode ocultos`
escape_control_characters=Escapar
unescape_control_characters=Desescapar
@@ -2773,11 +2767,11 @@ config.queue_length=Tamanho da fila
config.deliver_timeout=Intervalo de entrega
config.skip_tls_verify=Ignorar verificação de TLS
-config.mailer_config=Configuração SMTP para envio de e-mail
+config.mailer_config=Configuração de Envio de E-mail
config.mailer_enabled=Habilitado
-config.mailer_disable_helo=Desabilitar HELO
config.mailer_name=Nome
-config.mailer_host=Servidor
+config.mailer_protocol=Protocolo
+config.mailer_smtp_port=Porta SMTP
config.mailer_user=Usuário
config.mailer_use_sendmail=Usar o Sendmail
config.mailer_sendmail_path=Caminho do Sendmail
diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini
index 57254925c488..de7935e78bb5 100644
--- a/options/locale/locale_pt-PT.ini
+++ b/options/locale/locale_pt-PT.ini
@@ -9,7 +9,6 @@ sign_out=Terminar sessão
sign_up=Fazer inscrição
link_account=Vincular conta
register=Inscrição
-website=Sítio web
version=Versão
powered_by=Implementado com %s
page=Página
@@ -179,7 +178,8 @@ log_root_path_helper=Os ficheiros de registo serão escritos nesta pasta.
optional_title=Configurações opcionais
email_title=Configurações de email
-smtp_host=Servidor SMTP
+smtp_addr=Servidor SMTP
+smtp_port=Porto do SMTP
smtp_from=Email do remetente
smtp_from_helper=Endereço de email que o Gitea vai usar. Insira um endereço de email simples ou use o formato "Nome" .
mailer_user=Nome de utilizador do SMTP
@@ -1035,13 +1035,13 @@ file_view_rendered=Ver resultado processado
file_view_raw=Ver em bruto
file_permalink=Ligação permanente
file_too_large=O ficheiro é demasiado grande para ser apresentado.
-bidi_bad_header=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados!`
-bidi_bad_description=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres escondidos.`
-bidi_bad_description_escaped=`Este ficheiro contém caracteres Unicode Bidireccionais inesperados. Os caracteres escondidos unicode estão revelados abaixo. Use o botão Esconder para mostrar como é que eles são apresentados.`
-unicode_header=`Este ficheiro contém caracteres Unicode escondidos!`
-unicode_description=`Este ficheiro contém caracteres Unicode escondidos que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres escondidos.`
-unicode_description_escaped=`Este ficheiro contém caracteres Unicode escondidos. Os caracteres unicode escondidos estão revelados abaixo. Use o botão Esconder para mostrar como é que eles são apresentados.`
-line_unicode=`Esta linha tem caracteres unicode escondidos`
+invisible_runes_header=`Este ficheiro contém caracteres Unicode invisíveis!`
+invisible_runes_description=`Este ficheiro contém caracteres Unicode invisíveis que podem ser processados de forma diferente do que aparece abaixo. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para mostrar os caracteres invisíveis.`
+ambiguous_runes_header=`Este ficheiro contém caracteres Unicode ambíguos!`
+ambiguous_runes_description=`Este ficheiro contém caracteres Unicode ambíguos que podem ser confundidos com outros da sua configuração regional vigente. Se o uso é intencional e legítimo, pode ignorar este aviso com segurança. Use o botão Revelar para realçar esses caracteres.`
+invisible_runes_line=`Esta linha tem caracteres unicode invisíveis`
+ambiguous_runes_line=`Esta linha tem caracteres unicode ambíguos`
+ambiguous_character=`%[1]c [U+%04[1]X] pode confundir-se com %[2]c [U+%04[2]X]`
escape_control_characters=Revelar
unescape_control_characters=Esconder
@@ -1062,6 +1062,7 @@ normal_view=Vista normal
line=linha
lines=linhas
+editor.add_file=Adicionar ficheiro
editor.new_file=Novo ficheiro
editor.upload_file=Carregar ficheiro
editor.edit_file=Editar ficheiro
@@ -1267,6 +1268,8 @@ issues.filter_milestone=Etapa
issues.filter_milestone_no_select=Todas as etapas
issues.filter_assignee=Encarregado
issues.filter_assginee_no_select=Todos os encarregados
+issues.filter_poster=Autor(a)
+issues.filter_poster_no_select=Todos os autores
issues.filter_type=Tipo
issues.filter_type.all_issues=Todas as questões
issues.filter_type.assigned_to_you=Atribuídas a si
@@ -2795,16 +2798,19 @@ config.queue_length=Tamanho da fila
config.deliver_timeout=Prazo da entrega
config.skip_tls_verify=Ignorar validação TLS
-config.mailer_config=Configuração da aplicação SMTP
+config.mailer_config=Configuração de envio de email
config.mailer_enabled=Habilitado
-config.mailer_disable_helo=Desabilitar HELO
+config.mailer_enable_helo=Habilitar HELO
config.mailer_name=Nome
-config.mailer_host=Servidor
+config.mailer_protocol=Protocolo
+config.mailer_smtp_addr=Endereço SMTP
+config.mailer_smtp_port=Porto do SMTP
config.mailer_user=Utilizador
config.mailer_use_sendmail=Usar o sendmail
config.mailer_sendmail_path=Caminho do sendmail
config.mailer_sendmail_args=Argumentos extras para o sendmail
config.mailer_sendmail_timeout=Tempo limite do Sendmail
+config.mailer_use_dummy=Fictício
config.test_email_placeholder=Email (ex.: teste@exemplo.com)
config.send_test_mail=Enviar email de teste
config.test_mail_failed=Falhou o envio de um email de teste para '%s': %v
@@ -2887,20 +2893,21 @@ monitor.queue.review_add=Rever/Adicionar trabalhadores
monitor.queue.configuration=Configuração inicial
monitor.queue.nopool.title=Sem agregado de trabalhadores
monitor.queue.nopool.desc=Esta fila engloba outras filas e ela própria não tem um agregado de trabalhadores.
-monitor.queue.wrapped.desc=Uma fila envolvente envolve uma fila de início lento, armazenando pedidos em fila num canal. Ela própria não tem um conjunto de tarefas.
+monitor.queue.wrapped.desc=Uma fila envolvente envolve uma fila de início lento, armazenando pedidos em fila num canal. Ela própria não tem um agregado de trabalhadores.
monitor.queue.persistable-channel.desc=Um canal persistente engloba duas filas, uma fila de canal que tem o seu próprio agregado de trabalhadores e uma fila de nível para pedidos persistentes de encerramentos anteriores. Ele próprio não tem um agregado de trabalhadores.
+monitor.queue.flush=Trabalhador descartável
monitor.queue.pool.timeout=Prazo
monitor.queue.pool.addworkers.title=Adicionar trabalhadores
monitor.queue.pool.addworkers.submit=Adicionar trabalhadores
-monitor.queue.pool.addworkers.desc=Adicione trabalhadores a este agregado com, ou sem, prazo. Se definir um prazo, estes trabalhadores serão removidos do agregado, após o fim do prazo.
+monitor.queue.pool.addworkers.desc=Adicione trabalhadores a este agregado com, ou sem, um prazo. Se definir um prazo, estes trabalhadores serão removidos do agregado, quando terminar esse prazo.
monitor.queue.pool.addworkers.numberworkers.placeholder=Número de trabalhadores
monitor.queue.pool.addworkers.timeout.placeholder=Insira 0 para indicar que não tem prazo
-monitor.queue.pool.addworkers.mustnumbergreaterzero=O número de trabalhadores a adicionar deve ser maior que zero
+monitor.queue.pool.addworkers.mustnumbergreaterzero=O número de trabalhadores a adicionar deve ser maior do que zero
monitor.queue.pool.addworkers.musttimeoutduration=O prazo tem que ser uma duração no formato golang (ex.: 5m) ou 0
monitor.queue.pool.flush.title=Despejar fila
-monitor.queue.pool.flush.desc=O despejo irá adicionar um trabalhador que termina assim que a fila esteja vazia ou o prazo acabe.
-monitor.queue.pool.flush.submit=Adicionar trabalhador de despejo
-monitor.queue.pool.flush.added=Foi adicionado um trabalhador de despejo para %[1]s
+monitor.queue.pool.flush.desc='Descartável' irá adicionar um trabalhador que termina assim que a fila esteja vazia ou o prazo acabe.
+monitor.queue.pool.flush.submit=Adicionar trabalhador descartável
+monitor.queue.pool.flush.added=Foi adicionado um trabalhador descartável para %[1]s
monitor.queue.pool.pause.title=Pausar fila
monitor.queue.pool.pause.desc=Pausar uma fila impede que ela processe dados
monitor.queue.pool.pause.submit=Pausar fila
@@ -2909,11 +2916,11 @@ monitor.queue.pool.resume.desc=Definir esta fila para continuar o trabalho
monitor.queue.pool.resume.submit=Retomar fila
monitor.queue.settings.title=Configurações do agregado
-monitor.queue.settings.desc=Os agregados crescem dinamicamente com um impulso em resposta à ocorrência de bloqueios na sua fila de trabalhadores. Essas mudanças não irão influenciar os grupos de trabalhadores correntes.
+monitor.queue.settings.desc=Os agregados crescem dinamicamente com um aumento em resposta à ocorrência de bloqueios na sua fila de trabalhadores. Essas mudanças não irão influenciar os grupos de trabalhadores correntes.
monitor.queue.settings.timeout=Prazo do impulso
monitor.queue.settings.timeout.placeholder=De momento %[1]v
monitor.queue.settings.timeout.error=O prazo tem que ser uma duração no formato golang (ex: 5m) ou 0
-monitor.queue.settings.numberworkers=Número de trabalhadores do impulso
+monitor.queue.settings.numberworkers=Aumentar o número de trabalhadores
monitor.queue.settings.numberworkers.placeholder=De momento %[1]d
monitor.queue.settings.numberworkers.error=O número de trabalhadores a adicionar tem que ser maior ou igual a zero
monitor.queue.settings.maxnumberworkers=Número máximo de trabalhadores
@@ -2925,14 +2932,14 @@ monitor.queue.settings.blocktimeout=Prazo do bloco corrente
monitor.queue.settings.blocktimeout.value=%[1]v
monitor.queue.pool.none=Esta fila não tem um agregado
-monitor.queue.pool.added=Foi adicionado um agregado de trabalhadores
+monitor.queue.pool.added=Foi adicionado um grupo de trabalhadores
monitor.queue.pool.max_changed=O número máximo de trabalhadores mudou
monitor.queue.pool.workers.title=Grupos de trabalhadores operantes
-monitor.queue.pool.workers.none=Não há agregados de trabalhadores.
-monitor.queue.pool.cancel=Desligar agregado de trabalhadores
-monitor.queue.pool.cancelling=O agregado de trabalhadores está a encerrar
-monitor.queue.pool.cancel_notices=Desligar este agregado de %s trabalhadores?
-monitor.queue.pool.cancel_desc=Deixar uma fila sem quaisquer agregados de trabalhadores pode fazer com que os pedidos bloqueiem indefinidamente.
+monitor.queue.pool.workers.none=Não há grupos de trabalhadores.
+monitor.queue.pool.cancel=Desligar o grupo de trabalhadores
+monitor.queue.pool.cancelling=O grupo de trabalhadores está a encerrar
+monitor.queue.pool.cancel_notices=Desligar este grupo de %s trabalhadores?
+monitor.queue.pool.cancel_desc=Deixar uma fila sem quaisquer grupos de trabalhadores pode fazer com que os pedidos sejam bloqueados indefinidamente.
notices.system_notice_list=Notificações do sistema
notices.view_detail_header=Ver os detalhes da notificação
@@ -3107,6 +3114,10 @@ npm.dependencies.development=Dependências de desenvolvimento
npm.dependencies.peer=Dependências de pares
npm.dependencies.optional=Dependências opcionais
npm.details.tag=Etiqueta
+pub.install=Para instalar o pacote usando o Dart, execute o seguinte comando:
+pub.documentation=Para obter mais informações sobre o registo Pub, consulte a documentação .
+pub.details.repository_site=Página web do repositório
+pub.details.documentation_site=Página web da documentação
pypi.requires=Requer Python
pypi.install=Para instalar o pacote usando o pip, execute o seguinte comando:
pypi.documentation=Para obter mais informações sobre o registo do PyPI, consulte a documentação .
@@ -3114,6 +3125,8 @@ rubygems.install=Para instalar o pacote usando o gem, execute o seguinte comando
rubygems.install2=ou adicione-o ao ficheiro Gemfile
:
rubygems.dependencies.runtime=Dependências do tempo de execução (runtime)
rubygems.dependencies.development=Dependências de desenvolvimento
+rubygems.required.ruby=Requer a versão do Ruby
+rubygems.required.rubygems=Requer a versão do RubyGem
rubygems.documentation=Para obter mais informações sobre o registo do RubyGems, consulte a documentação .
settings.link=Vincular este pacote a um repositório
settings.link.description=Se você vincular um pacote a um repositório, o pacote será listado na lista de pacotes do repositório.
diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini
index ad8ee86d02e1..a185fe0cb074 100644
--- a/options/locale/locale_ru-RU.ini
+++ b/options/locale/locale_ru-RU.ini
@@ -9,7 +9,6 @@ sign_out=Выход
sign_up=Регистрация
link_account=Привязать аккаунт
register=Регистрация
-website=Веб-сайт
version=Версия
powered_by=Работает на %s
page=Страница
@@ -177,7 +176,6 @@ log_root_path_helper=Файлы журнала будут записыватьс
optional_title=Расширенные настройки
email_title=Настройки электронной почты
-smtp_host=Узел SMTP
smtp_from=Отправить эл. почту как
smtp_from_helper=Адрес электронной почты, который будет использоваться Gitea. Введите обычный адрес электронной почты или используйте формат "Имя" .
mailer_user=SMTP логин
@@ -2681,11 +2679,8 @@ config.queue_length=Длина очереди
config.deliver_timeout=Задержка доставки
config.skip_tls_verify=Пропустить проверку TLS
-config.mailer_config=Настройки почты
config.mailer_enabled=Почта включена
-config.mailer_disable_helo=Отключить HELO
config.mailer_name=Имя
-config.mailer_host=Сервер
config.mailer_user=Пользователь
config.mailer_use_sendmail=Использовать Sendmail
config.mailer_sendmail_path=Путь к Sendmail
diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini
index 069a871045c2..7e7b140f2690 100644
--- a/options/locale/locale_si-LK.ini
+++ b/options/locale/locale_si-LK.ini
@@ -8,7 +8,6 @@ sign_out=නික්මෙන්න
sign_up=ලියාපදිංචිය
link_account=ගිණුම සබැඳින්න
register=ලියාපදිංචිය
-website=වියමන අඩවිය
version=අනුවාදය
powered_by=%s මගින් බලගන්වා ඇත
page=පිටුව
@@ -151,7 +150,6 @@ log_root_path_helper=ලොග් ගොනු මෙම ඩිරෙක්ට
optional_title=වෛකල්පිත සැකසුම්
email_title=වි-තැපෑලේ සැකසුම්
-smtp_host=SMTP සත්කාරක
smtp_from=ලෙස වි-තැපෑල යවන්න
smtp_from_helper=විද්යුත් තැපැල් ලිපිනය Gitea භාවිතා කරනු ඇත. සරල විද්යුත් තැපැල් ලිපිනයක් ඇතුළත් කරන්න හෝ “නම” ආකෘතිය භාවිතා කරන්න.
mailer_user=SMTP පරිශීලක නාමය
@@ -2508,11 +2506,8 @@ config.queue_length=පෝලිම් දිග
config.deliver_timeout=කාලය ගලවාගන්න
config.skip_tls_verify=TLS සත්යාපනය මඟ හරින්න
-config.mailer_config=SMTP තැපැල්කරු වින්යාසය
config.mailer_enabled=සබල කර ඇත
-config.mailer_disable_helo=හෙලෝ අක්රීය කරන්න
config.mailer_name=නම
-config.mailer_host=සත්කාරක
config.mailer_user=පරිශීලක
config.mailer_use_sendmail=සෙන්ඩ්මේල් භාවිතා කරන්න
config.mailer_sendmail_path=සෙන්ඩ්මේල් මාර්ගය
diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini
index 717481ec5401..00d1034fc614 100644
--- a/options/locale/locale_sv-SE.ini
+++ b/options/locale/locale_sv-SE.ini
@@ -8,7 +8,6 @@ sign_out=Logga ut
sign_up=Registrera
link_account=Länka konto
register=Registrera dig
-website=Webbplats
version=Version
powered_by=Drivs av %s
page=Sida
@@ -60,7 +59,7 @@ forks=Forks
activities=Aktiviteter
pull_requests=Pull förfrågningar
-issues=Problem
+issues=Ärenden
milestones=Milstolpar
cancel=Avbryt
@@ -138,7 +137,6 @@ log_root_path_helper=Loggfiler kommer skrivas till denna katalog.
optional_title=Övriga inställningar
email_title=Mejlinställningar
-smtp_host=SMTP-server
smtp_from=Skicka Mejl Som
smtp_from_helper=Mejladress som Gitea kommer att använda. Anges i simpelt ('email@example.com') eller fullständigt ('Name ') format.
mailer_user=SMTP-Användarnamn
@@ -644,15 +642,19 @@ generate_from=Generera från
repo_desc=Beskrivning
repo_lang=Språk
repo_gitignore_helper=Välj .gitignore-mallar.
+repo_gitignore_helper_desc=Välj vilka filer som inte ska spåras från en lista med mallar för vanliga språk. Typiska artefakter som genereras av varje språk byggverktyg ingår i .gitignore som standard.
issue_labels=Ärendeetiketter
issue_labels_helper=Välj en grupp av ärendeetiketter.
license=Licens
license_helper=Välj licensfil.
+license_helper_desc=En licens styr vad andra kan och inte kan göra med din kod. Inte säker på vilken som är rätt för ditt projekt? Se Välj en licens.
readme=README
readme_helper=Välj en mall för README-filen.
+readme_helper_desc=Här kan du skriva en fullständig beskrivning för ditt projekt.
auto_init=Initiera utvecklingskatalog (Lägger till .gitignore, License and README)
create_repo=Skapa utvecklingskatalog
default_branch=Standardgren
+default_branch_helper=Den förvalda grenen är bas-gren för pull requests och kod-commits.
mirror_prune=Rensa
mirror_prune_desc=Ta bort förlegade fjärrföljande referenser
mirror_interval_invalid=Speglingsintervallen är inte giltig.
@@ -721,6 +723,7 @@ migrated_from_fake=Migrerad från %[1]s
migrate.migrate=Migrera från %s
migrate.migrating=Migrerar från %s ...
migrate.migrating_failed=Migrering från %s misslyckades.
+migrate.migrating_issues=Migrerar Ärenden
mirror_from=spegling av
forked_from=forkad från
@@ -907,7 +910,7 @@ issues.new.add_reviewer_title=Begär granskning
issues.choose.get_started=Kom igång
issues.choose.blank=Standard
issues.choose.blank_about=Skapa ett ärende från standardmall.
-issues.no_ref=Ingen branch/Tag specificerad
+issues.no_ref=Ingen Branch/Tag specificerad
issues.create=Skapa Ärende
issues.new_label=Ny etikett
issues.new_label_placeholder=Etikettsnamn
@@ -973,6 +976,7 @@ issues.commented_at=`kommenterad %s `
issues.delete_comment_confirm=Är du säker på att du vill ta bort den här kommentaren?
issues.context.copy_link=Kopiera länk
issues.context.quote_reply=Citerat svar
+issues.context.reference_issue=Referens i nytt ärende
issues.context.edit=Redigera
issues.context.delete=Ta bort
issues.no_content=Det finns inget innehåll än.
@@ -982,6 +986,7 @@ issues.reopen_issue=Återöppna
issues.reopen_comment_issue=Kommentera och återöppna
issues.create_comment=Kommentera
issues.closed_at=`stängde ärendet %[2]s `
+issues.reopened_at=`återöppnade detta ärende %[2]s `
issues.commit_ref_at=`refererade till detta ärende från en incheckning %[2]s `
issues.ref_issue_from=`refererade till detta ärende %[4]s %[2]s `
issues.ref_pull_from=`refererade till denna pull-förfrågan %[4]s %[2]s `
@@ -1039,10 +1044,13 @@ issues.lock.reason=Anledningen till att låsa
issues.lock.title=Lås konversationen för detta ärende.
issues.unlock.title=Lås upp konversation för ärendet.
issues.comment_on_locked=Du kan inte kommentera ett låst ärende.
+issues.delete.title=Radera detta ärende?
+issues.delete.text=Vill du verkligen ta bort detta ärende? (Detta kommer att permanent ta bort allt innehåll. Överväg att stänga det istället om du avser att hålla det arkiverat)
issues.tracker=Tidsredovisning
issues.start_tracking=Starta tidsredovisning
issues.start_tracking_history=`började arbeta %s`
issues.tracker_auto_close=Timern stoppas automatiskt när ärendet stängs
+issues.tracking_already_started=`Du har redan påbörjat tidredovisning på ett annat ärende !`
issues.stop_tracking_history=`slutade arbeta %s`
issues.cancel_tracking_history=”avbröt tidredovisning %s'
issues.add_time=Lägg till tid manuellt
@@ -1115,6 +1123,7 @@ issues.review.hide_resolved=Dölj löst
issues.review.resolve_conversation=Lös konversation
issues.review.resolved_by=markerade denna konversation som löst
issues.assignee.error=Inte alla tilldelade har lagts till på grund av ett oväntat fel.
+issues.content_history.options=Alternativ
pulls.desc=Aktivera pull-förfrågningar och kodgranskning.
@@ -1158,6 +1167,7 @@ pulls.invalid_merge_option=Du kan inte använda detta mergealternativet för den
; %[2]s %[3]s
pulls.open_unmerged_pull_exists=`Du kan inte återuppliva denna pull-request då det redan finns en identisk pull-request öppen (#%d).`
pulls.update_branch_success=Uppdatering av branchen lyckades
+pulls.update_not_allowed=Du är inte behörig att uppdatera grenen
pulls.outdated_with_base_branch=Denna branch är föråldrad gentemot bas-branchen
@@ -1270,6 +1280,7 @@ activity.git_stats_exclude_merges=Exkludera merger,
activity.git_stats_author_1=%d författare
activity.git_stats_author_n=%d författare
activity.git_stats_push_to_all_branches=till alla brancher.
+activity.git_stats_on_default_branch=På %s,
activity.git_stats_file_1=%d fil
activity.git_stats_file_n=%d filer
activity.git_stats_files_changed_1=har ändrats
@@ -1414,6 +1425,7 @@ settings.event_push=Pusha
settings.event_push_desc=Git push till en utvecklingskatalog.
settings.event_repository=Utvecklingskatalog
settings.event_repository_desc=Utvecklingskatalogen skapad eller borttagen.
+settings.event_header_issue=Ärendehändelser
settings.event_issues=Ärenden
settings.event_issue_comment=Kommentar
settings.event_issue_comment_desc=Kommentar skapad, ändrad eller borttagen.
@@ -1516,6 +1528,7 @@ settings.lfs_force_unlock=Tvinga upplåsning
settings.lfs_pointers.sha=Blob SHA
settings.lfs_pointers.oid=OID
settings.lfs_pointers.inRepo=I utvecklingskatalogen
+settings.rename_branch_failed_not_exist=Kan inte byta namn på branchen %s eftersom den inte finns.
diff.browse_source=Bläddra i källkod
diff.parent=förälder
@@ -1969,11 +1982,8 @@ config.queue_length=Kölängd
config.deliver_timeout=Tidsfrist för leverans
config.skip_tls_verify=Skippa TLS verifiering
-config.mailer_config=SMTP-Mailer konfiguration
config.mailer_enabled=Aktiverad
-config.mailer_disable_helo=Avaktivera HELO
config.mailer_name=Namn
-config.mailer_host=Server
config.mailer_user=Användare
config.mailer_use_sendmail=Använd Sendmail
config.mailer_sendmail_path=Sendmail sökväg
diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini
index 4197f14e5069..d92c46eae420 100644
--- a/options/locale/locale_tr-TR.ini
+++ b/options/locale/locale_tr-TR.ini
@@ -9,7 +9,6 @@ sign_out=Çıkış Yap
sign_up=Kaydol
link_account=Bağlantı hesabı
register=Üye Ol
-website=Web sitesi
version=Sürüm
powered_by=%s tarafından desteklenen
page=Sayfa
@@ -111,6 +110,7 @@ rss_feed=RSS Beslemesi
occurred=Bir hata oluştu
report_message=Bunun bir Gitea hatası olduğundan eminseniz, lütfen GitHub sayfasında sorunu arayın veya gerekiyorsa yeni bir sorun açın.
missing_csrf=Hatalı İstek: CSRF anahtarı yok
+invalid_csrf=Hatalı İstek: geçersiz CSRF erişim anahtarı
not_found=Hedef bulunamadı.
network_error=Ağ hatası
@@ -178,7 +178,8 @@ log_root_path_helper=Günlük dosyaları bu dizine kaydedilecektir.
optional_title=İsteğe Bağlı Ayarlar
email_title=E-posta Ayarları
-smtp_host=SMTP Sunucusu
+smtp_addr=SMTP Sunucusu
+smtp_port=SMTP Portu
smtp_from=E-posta Gönderen
smtp_from_helper=Gitea'nın kullanacağı e-posta adresi. Yalın bir e-posta adresi girin veya "İsim" biçimini kullanın.
mailer_user=SMTP Kullanıcı Adı
@@ -555,6 +556,7 @@ cancel=İptal
language=Dil
ui=Tema
hidden_comment_types=Gizli yorum türleri
+comment_type_group_reference=Referans
comment_type_group_label=Etiket
comment_type_group_milestone=Dönüm noktası
comment_type_group_assignee=Atanan
@@ -660,7 +662,13 @@ verify_gpg_key_success=GPG anahtarı '%s' doğrulandı.
ssh_key_verified=Doğrulanmış Anahtar
ssh_key_verified_long=Bu anahtar bir belirteç ile doğrulandı ve bu kullanıcı için etkinleştirilmiş herhangi bir e-posta adresi ile uyuşan işlemeleri doğrulamak için kullanılabilir.
ssh_key_verify=Doğrula
+ssh_invalid_token_signature=Verilen SSH anahtarı, imza veya erişim anahtarı uyuşmuyor veya erişim anahtarı çok eski.
+ssh_token_required=Aşağıdaki erişim anahtarı için bir imza sağlamalısınız
+ssh_token=Erişim Anahtarı
ssh_token_help=Şunu kullanarak bir imza oluşturabilirsiniz:
+ssh_token_signature=Korumalı SSH imzası
+key_signature_ssh_placeholder='-----BEGIN SSH SIGNATURE-----' ile başlar
+verify_ssh_key_success=SSH anahtarı '%s' doğrulandı.
subkeys=Alt anahtarlar
key_id=Anahtar Kimliği
key_name=Anahtar İsmi
@@ -708,6 +716,9 @@ generate_token_success=Yeni bir jeton oluşturuldu. Tekrar gösterilmeyeceği i
generate_token_name_duplicate=%s zaten bir uygulama adı olarak kullanılmış. Lütfen yeni bir tane kullanın.
delete_token=Sil
access_token_deletion=Erişim Jetonunu Sil
+access_token_deletion_cancel_action=İptal
+access_token_deletion_confirm_action=Sil
+access_token_deletion_desc=Bir erişim anahtarını silmek, onu kullanan uygulamaların hesabınıza erişimini kaldırır. Bu geri alınamaz. Devam edilsin mi?
delete_token_success=Jeton silindi. Onu kullanan uygulamalar artık hesabınıza erişemez.
manage_oauth2_applications=OAuth2 Uygulamalarını Yönet
@@ -760,10 +771,16 @@ passcode_invalid=Şifre geçersiz. Tekrar deneyin.
twofa_enrolled=Hesabınız iki faktörlü kimlik doğrulamasına kaydedildi. Kazıma belirtecini (%s) yalnızca bir kez gösterdiği gibi güvenli bir yerde saklayın!
twofa_failed_get_secret=Gizlilik elde edilemedi.
+webauthn_desc=Güvenlik anahtarları, şifreleme anahtarlarını içeren donanım aygıtlarıdır. İki aşamalı kimlik doğrulama için kullanılabilirler. Güvenlik anahtarları WebAuthn Authenticator standardını desteklemelidir.
+webauthn_register_key=Güvenlik Anahtarı Ekle
+webauthn_nickname=Takma Ad
+webauthn_delete_key=Güvenlik Anahtarını Kaldır
+webauthn_delete_key_desc=Bir güvenlik anahtarını kaldırırsanız, onunla artık giriş yapamazsınız. Devam edilsin mi?
manage_account_links=Bağlı Hesapları Yönet
manage_account_links_desc=Bu harici hesaplar Gitea hesabınızla bağlantılı.
account_links_not_available=Şu anda Gitea hesabınıza bağlı harici bir hesap yok.
+link_account=Hesap Bağla
remove_account_link=Bağlantılı Hesabı Kaldır
remove_account_link_desc=Bağlantılı bir hesabı kaldırmak, onunla Gitea hesabınıza erişimi iptal edecektir. Devam edilsin mi?
remove_account_link_success=Bağlantılı hesap kaldırıldı.
@@ -782,6 +799,7 @@ email_notifications.enable=E-posta Bildirimlerini Etkinleştir
email_notifications.onmention=Sadece Bahsedilen E-posta
email_notifications.disable=E-posta Bildirimlerini Devre Dışı Bırak
email_notifications.submit=E-posta Tercihlerini Ayarla
+email_notifications.andyourown=Ve Sizin Bildirimleriniz
visibility=Kullanıcı görünürlüğü
visibility.public=Herkese Açık
@@ -844,7 +862,9 @@ default_branch=Varsayılan Dal
default_branch_helper=Varsayılan dal, değişiklik istekleri ve kod işlemeleri için temel daldır.
mirror_prune=Buda
mirror_prune_desc=Kullanılmayan uzak depoları izleyen referansları kaldır
+mirror_interval=Yansı Aralığı (geçerli zaman birimleri 'h', 'm', 's'). Periyodik senkronizasyonu devre dışı bırakmak için 0 kullanın. (Asgari aralık: %s)
mirror_interval_invalid=Yansı süre aralığı geçerli değil.
+mirror_sync_on_commit=İşlemeler gönderildiğinde senkronize et
mirror_address=URL'den Klonla
mirror_address_desc=Yetkilendirme bölümüne gerekli tüm kimlik bilgilerini girin.
mirror_address_url_invalid=Sağlanan Url geçersiz. Url'nin tüm bileşenlerinden doğru olarak kaçmalısınız.
@@ -892,7 +912,8 @@ desc.archived=Arşivlenmiş
template.items=Şablon Öğeleri
template.git_content=Git İçeriği (Varsayılan Dal)
-template.git_hooks=Git İstekleri
+template.git_hooks=Git İstemcileri
+template.git_hooks_tooltip=Eklendikten sonra Git İstemcilerini değiştirmek veya kaldırmak mümkün değildir. Bunu yalnızca şablon deposuna güveniyorsanız seçin.
template.webhooks=Web İstemcileri
template.topics=Konular
template.avatar=Profil Resmi
@@ -912,6 +933,7 @@ form.name_pattern_not_allowed='%s' deseni, depo adı için geçerli değildir.
need_auth=Yetkilendirme
migrate_options=Göç Seçenekleri
migrate_service=Göç Hizmeti
+migrate_options_mirror_helper=Bu depo bir yansı olacaktır
migrate_options_lfs=LFS dosyalarını taşı
migrate_options_lfs_endpoint.label=LFS Uç Noktası
migrate_options_lfs_endpoint.description=Taşıma, LFS sunucusunu belirlemek için Git uzak sunucusunu kullanmaya çalışacak. Eğer LFS veri deposu başka yerdeyse özel bir uç nokta da belirtebilirsiniz.
@@ -928,8 +950,10 @@ migrate_items_releases=Sürümler
migrate_repo=Depoyu Göç Ettir
migrate.clone_address=URL'den Taşı / Klonla
migrate.clone_address_desc=Varolan bir deponun HTTP(S) veya Git 'klonlama' URL'si
+migrate.github_token_desc=GitHub API hız sınırı nedeniyle göçü hızlandırmak için buraya virgülle ayrılmış bir veya daha fazla erişm anahtarı koyabilirsiniz. UYARI: Bu özelliğin kötüye kullanılması, hizmet sağlayıcının politikasını ihlal edebilir ve hesabın engellenmesine yol açabilir.
migrate.clone_local_path=veya bir yerel sunucu yolu
migrate.permission_denied=Yerel depoları içeri aktarma izniniz yok.
+migrate.permission_denied_blocked=İzin verilmeyen sunuculardan içe aktaramazsınız, lütfen yöneticiden ALLOWED_DOMAINS/ALLOW_LOCALNETWORKS/BLOCKED_DOMAINS ayarlarını kontrol etmesini isteyin.
migrate.invalid_local_path=Yerel yol geçersiz. Mevcut değil veya bir dizin değil.
migrate.invalid_lfs_endpoint=LFS Uç noktası geçerli değil.
migrate.failed=Göç başarısız: %v
@@ -977,6 +1001,7 @@ clone_this_repo=Bu depoyu klonla
create_new_repo_command=Komut satırında yeni bir depo oluşturuluyor
push_exist_repo=Komut satırından mevcut bir depo itiliyor
empty_message=Bu depoda herhangi bir içerik yok.
+broken_message=Bu deponun altındaki Git verisi okunamıyor. Bu sunucunun yöneticisiyle bağlantıya geçin veya bu depoyu silin.
code=Kod
code.desc=Kaynak koda, dosyalara, işlemelere ve dallara eriş.
@@ -990,6 +1015,7 @@ tags=Etiket
issues=Konular
pulls=Değişiklik İstekleri
project_board=Projeler
+packages=Paketler
labels=Etiketler
org_labels_desc=Bu organizasyon altında tüm depolarla kullanılabilen organizasyon düzeyinde etiketler
org_labels_desc_manage=yönet
@@ -1001,6 +1027,7 @@ release=Sürüm
releases=Sürüm
tag=Etiket
released_this=bu sürümü yayınladı
+file.title=%s dalındaki/etiketindeki %s
file_raw=Ham
file_history=Geçmiş
file_view_source=Kaynağı Görüntüle
@@ -1008,7 +1035,18 @@ file_view_rendered=Oluşturulanları Görüntüle
file_view_raw=Ham Görünüm
file_permalink=Kalıcı Bağlantı
file_too_large=Bu dosya görüntülemek için çok büyük.
-
+invisible_runes_header=`Bu dosya görünmez Evrensel Kodlu karakter içeriyor!`
+invisible_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek görünmez Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Gizli karakterleri göstermek için Kaçış düğmesine tıklayın.`
+ambiguous_runes_header=`Bu dosya muğlak Evrensel Kodlu karakter içeriyor!`
+ambiguous_runes_description=`Bu dosya, aşağıda görünenden farklı bir şekilde işlenebilecek muğlak Evrensel Kodlu karakter içeriyor. Eğer bunu kasıtlı ve meşru olarak yaptıysanız bu uyarıyı yok sayabilirsiniz. Bu karakterleri göstermek için Kaçış düğmesine tıklayın.`
+invisible_runes_line=`Bu satırda görünmez evrensel kodlu karakter var`
+ambiguous_runes_line=`Bu satırda muğlak evrensel kodlu karakter var`
+ambiguous_character=`%[1]c [U+%04[1]X], %[2]c [U+%04[2]X] ile karıştırılabilir`
+
+escape_control_characters=Kaçış Karakterli
+unescape_control_characters=Kaçış Karaktersiz
+file_copy_permalink=Kalıcı Bağlantıyı Kopyala
+view_git_blame=Git Suç Görüntüle
video_not_supported_in_browser=Tarayıcınız HTML5 'video' etiketini desteklemiyor.
audio_not_supported_in_browser=Tarayıcınız HTML5 'audio' etiketini desteklemiyor.
stored_lfs=Git LFS ile depolandı
@@ -1024,6 +1062,7 @@ normal_view=Normal Görünüm
line=satır
lines=satır
+editor.add_file=Dosya Ekle
editor.new_file=Yeni dosya
editor.upload_file=Dosya Yükle
editor.edit_file=Dosyayı Düzenle
@@ -1086,6 +1125,8 @@ editor.cannot_commit_to_protected_branch=Korunan '%s' dalına işleme yapılamı
editor.no_commit_to_branch=Doğrudan dala işleme yapılamıyor çünkü:
editor.user_no_push_to_branch=Kullanıcı dala gönderemez
editor.require_signed_commit=Dal imzalı bir işleme gerektirir
+editor.cherry_pick=%s şunun üzerine cımbızla:
+editor.revert=%s şuna geri döndür:
commits.desc=Kaynak kodu değişiklik geçmişine göz atın.
commits.commits=İşleme
@@ -1109,6 +1150,7 @@ commits.ssh_key_fingerprint=SSH Anahtar Parmak İzi
commit.actions=Eylemler
commit.revert=Geri Al
commit.revert-header=Geri al: %s
+commit.revert-content=Geri almak için dal seçin:
commit.cherry-pick=Cımbızla
commit.cherry-pick-header=Cımbızla: %s
commit.cherry-pick-content=Cımbızlamak için dal seçin:
@@ -1150,6 +1192,7 @@ projects.board.deletion_desc=Bir proje panosunun silinmesi, ilgili tüm konular
projects.board.color=Renk
projects.open=Aç
projects.close=Kapat
+projects.board.assigned_to=Atanan
issues.desc=Hata raporlarını, görevleri ve kilometre taşlarını yönetmenizi sağlar.
issues.filter_assignees=Atama Süzgeci
@@ -1214,6 +1257,9 @@ issues.add_assignee_at=`%[2]s %[1]s tarafından atandı`
issues.remove_assignee_at=`ataması %[2]s %[1]s tarafından kaldırıldı`
issues.remove_self_assignment=`atamalarını kaldırdı %s`
issues.change_title_at=`başlığı %s iken %s olarak %s değiştirdi`
+issues.change_ref_at=`%s referans %s %s olarak değiştirildi`
+issues.remove_ref_at=`%s referansı %s tarihinde kaldırıldı`
+issues.add_ref_at=`%s referansı %s tarihinde eklendi`
issues.delete_branch_at=`%s dalı silindi %s`
issues.filter_label=Etiket
issues.filter_label_exclude=`Etiketleri hariç tutmak için alt
+ tıkla/enter
kullanın`
@@ -1222,6 +1268,8 @@ issues.filter_milestone=Kilometre Taşı
issues.filter_milestone_no_select=Tüm kilometre taşları
issues.filter_assignee=Atanan
issues.filter_assginee_no_select=Tüm atananlar
+issues.filter_poster=Yazar
+issues.filter_poster_no_select=Tüm yazarlar
issues.filter_type=Tür
issues.filter_type.all_issues=Tüm konular
issues.filter_type.assigned_to_you=Size atanan
@@ -1241,6 +1289,7 @@ issues.filter_sort.moststars=En çok yıldızlılar
issues.filter_sort.feweststars=En az yıldızlılar
issues.filter_sort.mostforks=En çok çatallananlar
issues.filter_sort.fewestforks=En az çatallananlar
+issues.keyword_search_unavailable=Anahtar kelime ile arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
issues.action_open=Açık
issues.action_close=Kapat
issues.action_label=Etiket
@@ -1249,7 +1298,11 @@ issues.action_milestone_no_select=Kilometre Taşı Yok
issues.action_assignee=Atanan
issues.action_assignee_no_select=Atanan yok
issues.opened_by=%[3]s tarafından %[1]s açıldı
+pulls.merged_by=%[1]s %[3]s tarafından açılan istek birleştirildi
+pulls.merged_by_fake=%[2]s tarafından açılan istek %[1]s birleştirildi
+issues.closed_by=%[3]s tarafından %[1]s kapatıldı
issues.opened_by_fake=%[2]s tarafından %[1]s açıldı
+issues.closed_by_fake=%[2]s tarafından %[1]s kapatıldı
issues.previous=Önceki
issues.next=Sonraki
issues.open_title=Açık
@@ -1370,7 +1423,8 @@ issues.due_date_form_edit=Düzenle
issues.due_date_form_remove=Kaldır
issues.due_date_not_writer=Bir konunun bitiş tarihini değiştirmek için depoda yazma hakkınız olmalıdır.
issues.due_date_not_set=Bitiş tarihi atanmadı.
-issues.due_date_added=%[2]s %[1]s bitiş tarihini ekledi
+issues.due_date_added=bitiş tarihini %s olarak %s ekledi
+issues.due_date_modified=bitiş tarihini %[2]s iken %[1]s olarak %[3]s değiştirdi
issues.due_date_remove=%[2]s %[1]s bitiş tarihini kaldırdı
issues.due_date_overdue=Süresi Geçmiş
issues.due_date_invalid=Bitiş tarihi geçersiz veya aralık dışında. Lütfen 'yyyy-aa-gg' biçimini kullanın.
@@ -1432,6 +1486,7 @@ issues.content_history.deleted=silindi
issues.content_history.edited=düzenlendi
issues.content_history.created=oluşturuldu
issues.content_history.delete_from_history=Geçmişten kaldır
+issues.content_history.delete_from_history_confirm=Geçmişten kaldırılsın mı?
issues.content_history.options=Seçenekler
issues.reference_link=Referans: %s
@@ -1442,6 +1497,8 @@ pulls.desc=Değişiklik isteklerini ve kod incelemelerini etkinleştir.
pulls.new=Yeni Değişiklik İsteği
pulls.view=Değişiklik İsteği Görüntüle
pulls.compare_changes=Yeni Değişiklik İsteği
+pulls.allow_edits_from_maintainers=Bakımcıların düzenlemelerine izin ver
+pulls.allow_edits_from_maintainers_desc=Ana dala yazma hakkı olan kullanıcılar bu dala da gönderebilirler
pulls.allow_edits_from_maintainers_err=Güncelleme başarısız oldu
pulls.compare_changes_desc=Birleştirmek için hedef ve kaynak dalı seçin.
pulls.has_viewed_file=Görüldü
@@ -1524,7 +1581,10 @@ pulls.rebase_conflict_summary=Hata Mesajı
; %[2]s %[3]s
pulls.unrelated_histories=Birleştirme Başarısız: Birleştirme başlığı ve tabanı ortak bir geçmişi paylaşmıyor. İpucu: Farklı bir strateji deneyin
pulls.merge_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, taban güncellendi. İpucu: Tekrar deneyin.
+pulls.head_out_of_date=Birleştirme Başarısız: Birleştirme oluşturulurken, ana güncellendi. İpucu: Tekrar deneyin.
+pulls.push_rejected=Birleştirme Başarısız Oldu: Gönderme reddedildi. Bu depo için Git İstemcilerini inceleyin.
pulls.push_rejected_summary=Tam Red Mesajı
+pulls.push_rejected_no_message=Birleştirme başarısız oldu: Gönderme reddedildi, ancak uzak bir mesaj yoktu. Bu depo için Git İstemcilerini inceleyin
pulls.open_unmerged_pull_exists=`Aynı özelliklere sahip bekleyen bir değişiklik isteği (#%d) olduğundan yeniden açma işlemini gerçekleştiremezsiniz.`
pulls.status_checking=Bazı denetlemeler beklemede
pulls.status_checks_success=Tüm denetlemeler başarılı oldu
@@ -1547,9 +1607,17 @@ pulls.merge_instruction_step2_desc=Gitea'daki değişiklikleri ve güncellemeler
pulls.auto_merge_button_when_succeed=(Denetlemeler başarılı olduğunda)
pulls.auto_merge_when_succeed=Tüm denetlemeler başarılı olduğundan otomatik olarak birleştir
pulls.auto_merge_newly_scheduled=Değişiklik İsteği tüm denetlemeler başarılı olduğunda birleştirilecek şekilde ayarlanmış.
+pulls.auto_merge_has_pending_schedule=%[1]s, bu değişiklik isteğini tüm denetlemeler başarılı olduğunda %[2]s, otomatik olarak birleşecek şekilde ayarlamış.
+pulls.auto_merge_cancel_schedule=Otomatik birleştirmeyi iptal et
+pulls.auto_merge_not_scheduled=Bu değişiklik isteği için otomatik birleştirme zamanlanmamış.
+pulls.auto_merge_canceled_schedule=Bu değişiklik isteği için otomatik birleştirme iptal edildi.
+pulls.auto_merge_newly_scheduled_comment=`bu değişiklik isteği, tüm denetlemeler başarılı olduğunda %[1]s, otomatik olarak birleşecek şekilde ayarlandı`
+pulls.auto_merge_canceled_schedule_comment=`bu değişiklik isteğinin, tüm denetlemeler başarılı olduğunda %[1]s, otomatik birleştirmesi iptal edildi`
+pulls.delete.title=Bu değişiklik isteği silinsin mi?
+pulls.delete.text=Bu değişiklik isteğini gerçekten silmek istiyor musunuz? (Bu işlem tüm içeriği kalıcı olarak silecektir. Arşivde tutma niyetiniz varsa silmek yerine kapatmayı düşünün)
milestones.new=Yeni Kilometre Taşı
milestones.closed=Kapalı %s
@@ -1595,6 +1663,7 @@ signing.wont_sign.commitssigned=İlişkili tüm işlemeler imzalanmadığı içi
signing.wont_sign.approved=Değişiklik İsteği onaylanmadığı için birleştirme imzalanmayacak
signing.wont_sign.not_signed_in=Oturum açmadınız
+ext_wiki=Harici Vikiye Erişim
ext_wiki.desc=Harici bir wiki'ye bağlantı.
wiki=Wiki
@@ -1619,6 +1688,7 @@ wiki.page_already_exists=Aynı isimde bir Wiki sayfası zaten var.
wiki.reserved_page='%s' wiki sayfa adı rezerve edilmiştir.
wiki.pages=Sayfalar
wiki.last_updated=Son güncelleme %s
+wiki.page_name_desc=Bu Viki sayfası için bir ad girin. Bazı özel isimler 'Home', '_Sidebar' ve '_Footer' şeklindedir.
activity=Aktivite
activity.period.filter_label=Dönem:
@@ -1691,6 +1761,8 @@ search.search_repo=Depo ara
search.fuzzy=Belirsiz
search.match=Eşleştir
search.results="%s" için %s içinde sonuçları ara
+search.code_no_results=Arama teriminizle eşleşen bir kaynak kod bulunamadı.
+search.code_search_unavailable=Kod arama şu an mevcut değil. Lütfen site yöneticisiyle iletişime geçin.
settings=Ayarlar
settings.desc=Ayarlar, depo için ayarları yönetebileceğiniz yerdir
@@ -1702,7 +1774,7 @@ settings.collaboration.read=Oku
settings.collaboration.owner=Sahibi
settings.collaboration.undefined=Belirsiz
settings.hooks=Web İstemcileri
-settings.githooks=Git İstekleri
+settings.githooks=Git İstemcileri
settings.basic_settings=Temel Ayarlar
settings.mirror_settings=Yansıma Ayarları
settings.mirror_settings.docs=Projenizi, değişiklikleri başka bir depoya/depodan otomatik olarak gönderecek ve/veya çekecek şekilde ayarlayın. Dallar, etiketler ve işlemeler otomatik olarak senkronize edilecektir. Depoları nasıl yansıtrım?
@@ -1737,6 +1809,9 @@ settings.tracker_url_format_error=Harici konu izleyici URL biçimi geçerli bir
settings.tracker_issue_style=Harici Konu İzleyici Numara Biçimi
settings.tracker_issue_style.numeric=Sayısal
settings.tracker_issue_style.alphanumeric=Alfanumerik
+settings.tracker_issue_style.regexp=Düzenli ifade
+settings.tracker_issue_style.regexp_pattern=Düzenli İfade Kalıbı
+settings.tracker_issue_style.regexp_pattern_desc={index}
yerine ilk eşleşen grup kullanılacaktır.
settings.tracker_url_format_desc=Kullanıcı adı, depo adı ve yayın dizini için {user}
, {repo}
ve {index}
yer tutucularını kullanın.
settings.enable_timetracker=Zaman Takibini Etkinleştir
settings.allow_only_contributors_to_track_time=Sadece Katkıcılar İçin Zaman Takibine İzin Ver
@@ -1748,10 +1823,18 @@ settings.pulls.allow_rebase_merge_commit=Açık birleştirme işlemeleri ile Yen
settings.pulls.allow_squash_commits=İşlemeleri Birleştirmek için Ezmeyi Etkinleştir
settings.pulls.allow_manual_merge=Dİ'yi elle birleştirilmiş olarak işaretlemeyi etkinleştir
settings.pulls.enable_autodetect_manual_merge=Kendiliğinden algılamalı elle birleştirmeyi etkinleştir (Not: Bazı özel durumlarda yanlış kararlar olabilir)
+settings.pulls.allow_rebase_update=Değişiklik isteği dalının yeniden yapılandırmayla güncellenmesine izin ver
settings.pulls.default_delete_branch_after_merge=Varsayılan olarak birleştirmeden sonra değişiklik isteği dalını sil
+settings.packages_desc=Depo Paket Kütüğünü Etkinleştir
settings.projects_desc=Depo Projelerini Etkinleştir
settings.admin_settings=Yönetici Ayarları
settings.admin_enable_health_check=Depo Sağlık Kontrollerini Etkinleştir (git fsck)
+settings.admin_code_indexer=Kod Dizinleyici
+settings.admin_stats_indexer=Kod İstatistiği Dizinleyici
+settings.admin_indexer_commit_sha=Son Dizinlenen SHA
+settings.admin_indexer_unindexed=Dizinlenmemiş
+settings.reindex_button=Yeniden Dizinleme Kuyruğuna Ekle
+settings.reindex_requested=Yeniden Dizinleme İstendi
settings.admin_enable_close_issues_via_commit_in_any_branch=Varsayılan olmayan bir dalda yapılan bir işlemeyle konuyu kapat
settings.danger_zone=Tehlike Alanı
settings.new_owner_has_same_repo=Yeni sahibin aynı isimde başka bir deposu var. Lütfen farklı bir isim seçin.
@@ -1840,6 +1923,9 @@ settings.webhook.response=Cevaplar
settings.webhook.headers=Başlıklar
settings.webhook.payload=İçerik
settings.webhook.body=Gövde
+settings.webhook.replay.description=Bu web kancasını tekrar çalıştır.
+settings.webhook.delivery.success=Teslim kuyruğuna bir olay eklendi. Teslim geçmişinde görünmesi birkaç saniye alabilir.
+settings.githooks_desc=Git İstemcileri Git'in kendisi tarafından desteklenmektedir. Özel işlemler ayarlamak için aşağıdaki istemci dosyalarını düzenleyebilirsiniz.
settings.githook_edit_desc=İstek aktif değilse örnek içerik sunulacaktır. İçeriği boş bırakmak, isteği devre dışı bırakmayı beraberinde getirecektir.
settings.githook_name=İstek İsmi
settings.githook_content=İstek İçeriği
@@ -1851,6 +1937,7 @@ settings.content_type=POST İçerik Türü
settings.secret=Gizli
settings.slack_username=Kullanıcı Adı
settings.slack_icon_url=Simge Bağlantısı
+settings.slack_color=Renk
settings.discord_username=Kullanıcı adı
settings.discord_icon_url=Simge URL'si
settings.event_desc=Tetikleyici Açık:
@@ -1896,6 +1983,8 @@ settings.event_pull_request_review=Değişiklik İsteği İncelendi
settings.event_pull_request_review_desc=Değişiklik isteği onaylandı, reddedildi veya yorumu incelendi.
settings.event_pull_request_sync=Değişiklik İsteği Senkronize Edildi
settings.event_pull_request_sync_desc=Değişiklik isteği senkronize edildi.
+settings.event_package=Paket
+settings.event_package_desc=Bir depoda paket oluşturuldu veya silindi.
settings.branch_filter=Dal filtresi
settings.branch_filter_desc=Gönderme, dal oluşturma ve dal silme olayları için glob deseni olarak belirtilen dal beyaz listesi. Boşsa veya *
ise, tüm dallar için olaylar raporlanır. Sözdizimi için github.com/gobwas/glob belgelerine bakın. Örnekler: master
, {master,release*}
.
settings.active=Etkin
@@ -1909,6 +1998,23 @@ settings.hook_type=İstek Türü
settings.slack_token=Erişim Anahtarı
settings.slack_domain=Alan Adı
settings.slack_channel=Kanal
+settings.add_web_hook_desc=%s web kancasını deponuza ekleyin.
+settings.web_hook_name_gitea=Gitea
+settings.web_hook_name_gogs=Gogs
+settings.web_hook_name_slack=Slack
+settings.web_hook_name_discord=Discord
+settings.web_hook_name_dingtalk=DingTalk
+settings.web_hook_name_telegram=Telegram
+settings.web_hook_name_matrix=Matrix
+settings.web_hook_name_msteams=Microsoft Teams
+settings.web_hook_name_feishu_or_larksuite=Feishu / Lark Suite
+settings.web_hook_name_feishu=Feishu
+settings.web_hook_name_larksuite=Lark Suite
+settings.web_hook_name_wechatwork=WeCom (Wechat Work)
+settings.web_hook_name_packagist=Packagist
+settings.packagist_username=Packagist kullanıcı adı
+settings.packagist_api_token=API erişim anahtarı
+settings.packagist_package_url=Packagist paket URL'si
settings.deploy_keys=Dağıtım Anahtarları
settings.add_deploy_key=Dağıtım Anahtarı Ekle
settings.deploy_key_desc=Dağıtım anahtarları, depoyu salt okunur çekme yetkisine sahip.
@@ -2036,6 +2142,12 @@ settings.lfs_pointers.inRepo=Depoda
settings.lfs_pointers.exists=Mağazada var
settings.lfs_pointers.accessible=Kullanıcı tarafından erişilebilir
settings.lfs_pointers.associateAccessible=Erişilebilir %d OID ilişkilendirme
+settings.rename_branch_failed_exist=%s dalı zaten mevcut olduğu için dalın adı değiştirilemiyor.
+settings.rename_branch_failed_not_exist=%s dalının adı değiştirilemiyor, çünkü böyle bir dal yok.
+settings.rename_branch_success=%s dalının adı başarılı bir şekilde %s oldu.
+settings.rename_branch_from=önceki dal adı
+settings.rename_branch_to=yeni dal adı
+settings.rename_branch=Dalı yeniden adlandır
diff.browse_source=Kaynağa Gözat
diff.parent=ebeveyn
@@ -2065,6 +2177,9 @@ diff.file_image_height=Yükseklik
diff.file_byte_size=Boyut
diff.file_suppressed=Dosya farkı çok büyük olduğundan ihmal edildi
diff.file_suppressed_line_too_long=Dosya farkları bir veya daha fazla satır çok uzun olduğundan bastırıldı
+diff.too_many_files=Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor
+diff.show_more=Daha Fazla Göster
+diff.load=Fark Yükle
diff.generated=üretilen
diff.vendored=sağlanmış
diff.comment.placeholder=Yorum Yap
@@ -2084,6 +2199,7 @@ diff.protected=Korumalı
diff.image.side_by_side=Yan Yana
diff.image.swipe=Kaydır
diff.image.overlay=Arayüz
+diff.has_escaped=Bu satırda gizli evrensel kod karakterler var
releases.desc=Proje sürümlerini ve indirmeleri takip edin.
release.releases=Sürümler
@@ -2154,10 +2270,15 @@ branch.included_desc=Bu dal varsayılan dalın bir parçasıdır
branch.included=Dahil
branch.create_new_branch=Şu daldan dal oluştur:
branch.confirm_create_branch=Dal oluştur
+branch.create_branch_operation=Dal oluştur
branch.new_branch=Yeni dal oluştur
branch.new_branch_from='%s' dalından yeni dal oluştur
+branch.renamed=%s dalının adı %s olarak değiştirildi.
tag.create_tag=%s etiketi oluştur
+tag.create_tag_operation=Etiket oluştur
+tag.confirm_create_tag=Etiket oluştur
+tag.create_tag_from='%s' kullanarak yeni etiket oluştur
tag.create_success='%s' etiketi oluşturuldu.
@@ -2166,6 +2287,8 @@ topic.done=Bitti
topic.count_prompt=25'ten fazla konu seçemezsiniz
topic.format_prompt=Konular bir harf veya rakamla başlamalı, kısa çizgiler ('-') içerebilir ve en fazla 35 karakter uzunluğunda olabilir.
+find_file.go_to_file=Dosyaya git
+find_file.no_matching=Eşleşen dosya bulunamadı
error.csv.too_large=Bu dosya çok büyük olduğu için işlenemiyor.
error.csv.unexpected=%d satırı ve %d sütununda beklenmeyen bir karakter içerdiğinden bu dosya işlenemiyor.
@@ -2246,7 +2369,13 @@ teams.leave=Ayrıl
teams.leave.detail=%s bırakılsın mı?
teams.can_create_org_repo=Depoları oluştur
teams.can_create_org_repo_helper=Üyeler organizasyonda yeni depolar oluşturabilirler. Oluşturan yeni depoya yönetici erişimi sağlayacak.
+teams.none_access=Erişim Yok
+teams.none_access_helper=Üyeler bu birimi görüntüleyemez veya üzerinde başka bir işlem yapamaz.
+teams.general_access=Genel Erişim
+teams.general_access_helper=Üyelerin izinleri aşağıdaki izin tablosuna göre kararlaştırılacaktır.
+teams.read_access=Okuma
teams.read_access_helper=Üyeler, takım depolarını görüntüleyebilir ve klonlayabilir.
+teams.write_access=Yazma
teams.write_access_helper=Üyeler takım depolarını okuyabilir ve itme yapabilir.
teams.admin_access=Yönetici Erişimi
teams.admin_access_helper=Üyeler takım depolarını çekip itebilir ve katkıcı ekleyebilir.
@@ -2297,6 +2426,7 @@ first_page=İlk
last_page=Son
total=Toplam: %d
+dashboard.new_version_hint=Gitea %s şimdi hazır, %s çalıştırıyorsunuz. Ayrıntılar için blog 'a bakabilirsiniz.
dashboard.statistic=Özet
dashboard.operations=Bakım İşlemleri
dashboard.system_status=Sistem Durumu
@@ -2339,6 +2469,7 @@ dashboard.resync_all_hooks=Tüm depoların alma öncesi, güncelleme ve alma son
dashboard.reinit_missing_repos=Kayıtları bulunanlar için tüm eksik Git depolarını yeniden başlat
dashboard.sync_external_users=Harici kullanıcı verisini senkronize et
dashboard.cleanup_hook_task_table=Hook_task tablosunu temizleme
+dashboard.cleanup_packages=Süresi dolmuş paketleri temizleme
dashboard.server_uptime=Sunucunun Ayakta Kalma Süresi
dashboard.current_goroutine=Güncel Goroutine'ler
dashboard.current_memory_usage=Güncel Bellek Kullanımı
@@ -2370,6 +2501,8 @@ dashboard.last_gc_pause=Son GC Durması
dashboard.gc_times=GC Zamanları
dashboard.delete_old_actions=Veritabanından tüm eski eylemleri sil
dashboard.delete_old_actions.started=Veritabanından başlatılan tüm eski eylemleri silin.
+dashboard.update_checker=Denetleyiciyi güncelle
+dashboard.delete_old_system_notices=Veritabanından tüm eski sistem bildirimlerini sil
users.user_manage_panel=Kullanıcı Hesap Yönetimi
users.new_account=Yeni Kullanıcı Hesabı
@@ -2404,10 +2537,26 @@ users.allow_import_local=Yerel Depoları Alabilir
users.allow_create_organization=Organizasyon Oluşturabilir
users.update_profile=Kullanıcı Hesabını Güncelle
users.delete_account=Kullanıcı Hesabını Sil
+users.cannot_delete_self=Kendinizi silemezsiniz
users.still_own_repo=Bu kullanıcı hala bir veya daha fazla depoya sahip. Önce bu depoları silin veya transfer edin.
users.still_has_org=Bu kullanıcı bir organizasyonun üyesidir. Önce kullanıcıyı tüm organizasyonlardan çıkarın.
+users.purge=Kullanıcıyı Temizle
+users.purge_help=Kullanıcıyı ve sahip olduğu herhangi bir depoyu, organizasyonu ve paketleri zorla sil. Tüm yorumlar da silinecektir.
+users.still_own_packages=Kullanıcının bir veya daha fazla paketi var. Önce bu paketleri silin.
users.deletion_success=Kullanıcı hesabı silindi.
users.reset_2fa=2FD'yi sıfırla
+users.list_status_filter.menu_text=Filtre
+users.list_status_filter.reset=Sıfırla
+users.list_status_filter.is_active=Etkin
+users.list_status_filter.not_active=Etkin değil
+users.list_status_filter.is_admin=Yönetici
+users.list_status_filter.not_admin=Yönetici Değil
+users.list_status_filter.is_restricted=Kısıtlanmış
+users.list_status_filter.not_restricted=Kısıtlanmamış
+users.list_status_filter.is_prohibit_login=Oturum Açmayı Önle
+users.list_status_filter.not_prohibit_login=Oturum Açmaya İzin Ver
+users.list_status_filter.is_2fa_enabled=2FA Etkin
+users.list_status_filter.not_2fa_enabled=2FA Devre Dışı
emails.email_manage_panel=Kullanıcı E-posta Yönetimi
emails.primary=Birincil
@@ -2440,6 +2589,16 @@ repos.forks=Çatallar
repos.issues=Konular
repos.size=Boyut
+packages.package_manage_panel=Paket Yönetimi
+packages.total_size=Toplam Boyut: %s
+packages.owner=Sahibi
+packages.creator=Oluşturan
+packages.name=İsim
+packages.version=Sürüm
+packages.type=Tür
+packages.repository=Depo
+packages.size=Boyut
+packages.published=Yayınlandı
defaulthooks=Varsayılan Web İstemcileri
defaulthooks.desc=Web İstemcileri, belirli Gitea olayları tetiklendiğinde otomatik olarak HTTP POST isteklerini sunucuya yapar. Burada tanımlanan Web İstemcileri varsayılandır ve tüm yeni depolara kopyalanır. web istemcileri kılavuzunda daha fazla bilgi edinin.
@@ -2483,9 +2642,13 @@ auths.filter=Kullanıcı Filtresi
auths.admin_filter=Yönetici Filtresi
auths.restricted_filter=Kısıtlı Süzgeç
auths.restricted_filter_helper=Hiçbir kullanıcıyı kısıtlı olarak ayarlamamak için boş bırakın. Yönetici Süzgeci ile eşleşmeyen tüm kullanıcıları kısıtlanmış olarak ayarlamak için yıldız işareti ('*') kullanın.
+auths.verify_group_membership=LDAP'ta grup üyeliğini doğrula (atlamak için filtreyi boş bırakın)
auths.group_search_base=Grup Arama Tabanı DN
auths.group_attribute_list_users=Kullanıcı Listesi İçeren Grup Özelliği
auths.user_attribute_in_group=Grupta Listelenen Kullanıcı Özelliği
+auths.map_group_to_team=LDAP gruplarını Organizasyon takımlarına eşle (atlamak için bu alanı boş bırakın)
+auths.map_group_to_team_removal=Eğer kullanıcı ilişkili LDAP grubuna ait değilse, kullanıcıları eşleşmiş takımlardan çıkarın
+auths.enable_ldap_groups=LDAP gruplarını etkinleştir
auths.ms_ad_sa=MS AD Arama Nitelikleri
auths.smtp_auth=SMTP Yetkilendirme Türü
auths.smtphost=SMTP Sunucusu
@@ -2513,6 +2676,14 @@ auths.oauth2_emailURL=E-posta URL'si
auths.skip_local_two_fa=Yerel 2FA'yı atla
auths.skip_local_two_fa_helper=Bunu seçmediğinizde, 2FA ayarlamış olan yerel kullanıcıların, giriş yapabilmek için 2FA'yı yine de geçmeleri gerekiyor
auths.oauth2_tenant=Kiracı
+auths.oauth2_scopes=Ek Kapsamlar
+auths.oauth2_required_claim_name=Gerekli Talep İsmi
+auths.oauth2_required_claim_name_helper=Bu ismi, bu kaynağa oturum açmayı bu isimdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın
+auths.oauth2_required_claim_value=Gerekli Talep Değeri
+auths.oauth2_required_claim_value_helper=Bu değeri, bu kaynağa oturum açmayı bu isimdeki ve değerdeki talebe sahip kullanıcıların girişiyle sınırlamak için ayarlayın
+auths.oauth2_group_claim_name=Talep ismi bu kaynak için grup isimlerini sağlıyor. (İsteğe bağlı)
+auths.oauth2_admin_group=Yönetici kullanıcıları için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar)
+auths.oauth2_restricted_group=Kısıtlı kullanıcılar için Grup Talep değeri. (İsteğe bağlı, yukarıda talep ismine gerek duyar)
auths.enable_auto_register=Otomatik Kaydolmayı Etkinleştir
auths.sspi_auto_create_users=Kullanıcıları otomatik olarak oluştur
auths.sspi_auto_create_users_helper=SSPI kimlik doğrulama yönteminin ilk kez oturum açan kullanıcılar için otomatik olarak yeni hesaplar oluşturmasına izin ver
@@ -2560,6 +2731,7 @@ config.app_ver=Gitea Sürümü
config.app_url=Gitea Taban URL'si
config.custom_conf=Yapılandırma Dosyası Yolu
config.custom_file_root_path=Özel Dosya Kök Yolu
+config.domain=Sunucu Alan Adı
config.offline_mode=Yerel Kip
config.disable_router_log=Yönlendirici Log'larını Devre Dışı Bırak
config.run_user=Şu Kullanıcı Olarak Çalıştır
@@ -2575,6 +2747,7 @@ config.reverse_auth_user=Tersine Yetkilendirme Kullanıcısı
config.ssh_config=SSH Yapılandırması
config.ssh_enabled=Aktif
config.ssh_start_builtin_server=Yerleşik Sunucuyu Kullan
+config.ssh_domain=SSH Sunucusu Alan Adı
config.ssh_port=Bağlantı Noktası
config.ssh_listen_port=Port'u Dinle
config.ssh_root_path=Kök Yol
@@ -2625,16 +2798,19 @@ config.queue_length=Kuyruk Uzunluğu
config.deliver_timeout=Dağıtım Zaman Aşımı
config.skip_tls_verify=TLS Doğrulamasını Geç
-config.mailer_config=SMTP Mailer Yapılandırması
+config.mailer_config=Mailer Yapılandırması
config.mailer_enabled=Aktif
-config.mailer_disable_helo=HELO'yu Devre Dışı Bırak
+config.mailer_enable_helo=HELO'yu etkinleştir
config.mailer_name=İsim
-config.mailer_host=Sunucu
+config.mailer_protocol=Protokol
+config.mailer_smtp_addr=SMTP Adresi
+config.mailer_smtp_port=SMTP Portu
config.mailer_user=Kullanıcı
config.mailer_use_sendmail=Sendmail Kullan
config.mailer_sendmail_path=Sendmail Yolu
config.mailer_sendmail_args=Sendmail İçin İlave Değişkenler
config.mailer_sendmail_timeout=Sendmail Zaman Aşımı
+config.mailer_use_dummy=Sahte
config.test_email_placeholder=E-posta (ör. test@example.com)
config.send_test_mail=Test E-postası Gönder
config.test_mail_failed='%s' adresine test e-postası gönderilemedi: %v
@@ -2694,12 +2870,16 @@ monitor.next=Sonraki Zaman
monitor.previous=Önceki Zaman
monitor.execute_times=Çalıştırma
monitor.process=Çalışan Süreçler
+monitor.stacktrace=Yığın izleme
+monitor.goroutines=%d Gorutinleri
monitor.desc=Açıklama
monitor.start=Başlangıç Zamanı
monitor.execute_time=Çalıştırma Zamanı
+monitor.last_execution_result=Sonuç
monitor.process.cancel=İşlemi iptal et
monitor.process.cancel_desc=Bir işlemi iptal etmek veri kaybına neden olabilir
monitor.process.cancel_notices=İptal et: %s ?
+monitor.process.children=Çocuklar
monitor.queues=Kuyruklar
monitor.queue=Kuyruk: %s
monitor.queue.name=İsim
@@ -2707,6 +2887,7 @@ monitor.queue.type=Tür
monitor.queue.exemplar=Örnek Türü
monitor.queue.numberworkers=Çalışan Sayısı
monitor.queue.maxnumberworkers=En Fazla Çalışan Sayısı
+monitor.queue.numberinqueue=Kuyruktaki Sayı
monitor.queue.review=Yapılandırmayı İncele
monitor.queue.review_add=Çalışanları İncele/Ekle
monitor.queue.configuration=Başlangıç Yapılandırması
@@ -2714,6 +2895,7 @@ monitor.queue.nopool.title=Çalışan Havuzu Yok
monitor.queue.nopool.desc=Bu kuyruk diğer kuyrukları sarar ve kendisinin bir işçi havuzu yoktur.
monitor.queue.wrapped.desc=Sarılmış bir kuyruk, yavaş bir başlangıç kuyruğunu sararak kanaldaki kuyruk isteklerini arabelleğe alır. Bir işçi havuzu yoktur.
monitor.queue.persistable-channel.desc=Kesintisiz bir kanal, kendi alt havuzuna sahip bir kanal kuyruğu ve önceki kapanmalardan gelen kalıcı istekler için bir seviye kuyruğu olan iki kuyruğu sarar. Bir işçi havuzu yoktur.
+monitor.queue.flush=Çalışanı boşalt
monitor.queue.pool.timeout=Zaman aşımı
monitor.queue.pool.addworkers.title=Çalışan Ekle
monitor.queue.pool.addworkers.submit=Çalışan Ekle
@@ -2726,6 +2908,12 @@ monitor.queue.pool.flush.title=Kuyruk Temizleme
monitor.queue.pool.flush.desc=Temizleme, kuyruk boş olduğunda veya zaman aşımına uğradığında sona erecek bir işçi ekler.
monitor.queue.pool.flush.submit=Temizleme İşçisi Ekle
monitor.queue.pool.flush.added=%[1]s için Temizleme İşçisi eklendi
+monitor.queue.pool.pause.title=Kuyruğu Duraklat
+monitor.queue.pool.pause.desc=Kuyruğun duraklatılması veriyi işlemesini önleyecektir
+monitor.queue.pool.pause.submit=Kuyruğu Duraklat
+monitor.queue.pool.resume.title=Kuyruğu Sürdür
+monitor.queue.pool.resume.desc=Bu kuyruğun çalışmasını sürdür
+monitor.queue.pool.resume.submit=Kuyruğu Sürdür
monitor.queue.settings.title=Havuz Ayarları
monitor.queue.settings.desc=Havuzlar, çalışan kuyruğunun engellenmesine yanıt olarak dinamik bir şekilde büyür. Bu değişiklikler mevcut çalışan gruplarını etkilemeyecektir.
@@ -2771,18 +2959,34 @@ notices.delete_success=Sistem bildirimleri silindi.
[action]
create_repo=depo %s oluşturuldu
rename_repo=%[1]s
olan depo adını %[3]s buna çevirdi
+commit_repo=%[4]s deposuna %[3]s dalını gönderdi
create_issue=`%[3]s#%[2]s konusunu açtı`
close_issue=`%[3]s#%[2]s konusunu kapattı`
reopen_issue=`%[3]s#%[2]s konusunu tekrar açtı`
+create_pull_request=`%[3]s#%[2]s değişiklik isteğini oluşturdu`
+close_pull_request=`%[3]s#%[2]s değişiklik isteğini kapattı`
+reopen_pull_request=`%[3]s#%[2]s değişiklik isteğini yeniden açtı`
comment_issue=`%[3]s#%[2]s konusuna yorum yaptı`
+comment_pull=`%[3]s#%[2]s değişiklik isteğine yorum yaptı`
+merge_pull_request=`%[3]s#%[2]s değişiklik isteğini birleştirdi`
transfer_repo=depo %s
%s 'a aktarıldı
+push_tag=%[3]s etiketini %[4]s dalına gönderdi
delete_tag=%[2]s etiketi %[3]s deposundan silindi
delete_branch=%[3]s deposundan %[2]s dalı silindi
compare_branch=Karşılaştır
compare_commits=%d işlemeyi karşılaştır
compare_commits_general=İşlemeleri karşılaştır
+mirror_sync_push=yansıdan %[4]s deposundaki %[3]s dalına işlemeleri eşitledi
+mirror_sync_create=%[3]s yeni referansını, %[4]s olarak yansıdan eşledi
mirror_sync_delete=%[3]s adresindeki %[2]s
referansını eşitledi ve sildi
+approve_pull_request=`%[3]s#%[2]s değişiklik isteğini onayladı`
+reject_pull_request=`%[3]s#%[2]s için değişiklikler önerdi`
+publish_release=`%[3]s deposu için "%[4]s" sürümü yayınlandı`
+review_dismissed=`%[3]s#%[2]s için %[4]s yorumunu reddetti`
review_dismissed_reason=Sebep:
+create_branch=%[4]s deposunda %[3]s dalını oluşturdu
+starred_repo=%[2]s deposuna yıldız bıraktı
+watched_repo=%[2]s deposunu izlemeye başladı
[tool]
ago=%s önce
@@ -2835,8 +3039,104 @@ error.probable_bad_signature=UYARI! Veritabanında bu kimliğe sahip bir anahtar
error.probable_bad_default_signature=UYARI! Varsayılan anahtarın bu kimliği olmasına rağmen, bu işlemeyi doğrulamaz! Bu işleme ŞÜPHELİDİR.
[units]
+unit=Birim
error.no_unit_allowed_repo=Bu deponun hiçbir bölümüne erişme izniniz yok.
error.unit_not_allowed=Bu depo bölümüne erişme izniniz yok.
[packages]
+title=Paketler
+desc=Depo paketlerini yönet.
+empty=Henüz hiçbir paket yok.
+empty.documentation=Paket kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+empty.repo=Bir paket yüklediniz ama burada gösterilmiyor mu? Paket ayarları na gidin ve bu depoya bağlantı verin.
+filter.type=Tür
+filter.type.all=Tümü
+filter.no_result=Filtreniz herhangi bir sonuç döndürmedi.
+filter.container.tagged=Etiketlenmiş
+filter.container.untagged=Etiketlenmemiş
+published_by=%[1]s, %[3]s tarafından yayınlandı
+published_by_in=%[1]s, %[3]s tarafından %[5]s içerisinde yayınlanmış
+installation=Kurulum
+about=Bu paket hakkında
+requirements=Gereksinimler
+dependencies=Bağımlılıklar
+keywords=Anahtar Kelimeler
+details=Ayrıntılar
+details.author=Yazar
+details.project_site=Proje Web Sitesi
+details.license=Lisans
+assets=Varlıklar
+versions=Sürümler
+versions.on=açık
+versions.view_all=Tümünü görüntüle
+dependency.id=Kimlik
+dependency.version=Sürüm
+composer.registry=Bu kütüğü ~/.composer/config.json
dosyasında ayarlayın:
+composer.install=Paketi Composer ile kurmak için, şu komutu çalıştırın:
+composer.documentation=Composer kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+composer.dependencies=Bağımlılıklar
+composer.dependencies.development=Geliştirme Bağımlılıkları
+conan.details.repository=Depo
+conan.registry=Bu kütüğü komut satırını kullanarak kurun:
+conan.install=Conan ile paket kurmak için aşağıdaki komutu çalıştırın:
+conan.documentation=Conan kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+container.details.type=Görüntü Türü
+container.details.platform=Platform
+container.details.repository_site=Depo Sitesi
+container.details.documentation_site=Belge Sitesi
+container.pull=Görüntüyü komut satırını kullanarak çekin:
+container.documentation=Taşıyıcı kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+container.multi_arch=İşletim Sistemi / Mimari
+container.layers=Görüntü Katmanları
+container.labels=Etiketler
+container.labels.key=Anahtar
+container.labels.value=Değer
+generic.download=Paketi komut satırında indirin:
+generic.documentation=Genel kütük hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+helm.registry=Bu kütüğü komut satırını kullanarak kurun:
+helm.install=Paketi kurmak için, aşağıdaki komutu çalıştırın:
+helm.documentation=Helm kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+maven.registry=Bu kütüğü projenizdeki pom.xml
dosyasında ayarlayın:
+maven.install=Paketi kullanmak için aşağıdaki dependencies
parçasını pom.xml
dosyasınıza ekleyin:
+maven.install2=Komut satırında çalıştırın:
+maven.download=Bağımlılığı indirmek için, komut satırında çalıştırın:
+maven.documentation=Maven kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+nuget.registry=Bu kütüğü komut satırını kullanarak kurun:
+nuget.install=Paketi NuGet ile kurmak için, şu komutu çalıştırın:
+nuget.documentation=NuGet kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+nuget.dependency.framework=Hedef Çerçeve
+npm.registry=Bu kütüğü projenizdeki .npmrc
dosyasında ayarlayın:
+npm.install=Paketi npm ile kurmak için, şu komutu çalıştırın:
+npm.install2=veya paketi package.json dosyasına ekleyin:
+npm.documentation=Npm kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+npm.dependencies=Bağımlılıklar
+npm.dependencies.development=Geliştirme Bağımlılıkları
+npm.dependencies.peer=Eş Bağımlılıkları
+npm.dependencies.optional=İsteğe Bağlı Bağımlılıklar
+npm.details.tag=Etiket
+pub.install=Paketi Dart ile kurmak için, şu komutu çalıştırın:
+pub.documentation=Pub kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+pub.details.repository_site=Depo Sitesi
+pub.details.documentation_site=Belge Sitesi
+pypi.requires=Gereken Python
+pypi.install=Paketi pip ile kurmak için, şu komutu çalıştırın:
+pypi.documentation=PyPI kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+rubygems.install=Paketi gem ile kurmak için, şu komutu çalıştırın:
+rubygems.install2=veya paketi Gemfile dosyasına ekleyin:
+rubygems.dependencies.runtime=Çalışma Zamanı Bağımlılıkları
+rubygems.dependencies.development=Geliştirme Bağımlılıkları
+rubygems.required.ruby=Gereken Ruby sürümü
+rubygems.required.rubygems=Gereken RubyGem sürümü
+rubygems.documentation=RubyGems kütüğü hakkında daha fazla bilgi için, belgeye bakabilirsiniz.
+settings.link=Bu paketi bir depoya bağlayın
+settings.link.description=Eğer bir paketi bir depoya bağlarsanız, paket deponun paket listesinde listelenecektir.
+settings.link.select=Depo Seç
+settings.link.button=Depo Bağlantısını Güncelle
+settings.link.success=Depo bağlantısı başarıyla güncellendi.
+settings.link.error=Depo bağlantısı güncellenemedi.
+settings.delete=Paket Sil
+settings.delete.description=Bir paketi silmek kalıcıdır ve geri alınamaz.
+settings.delete.notice=%s (%s) paketini silmek üzeresiniz. Bu işlem geri alınamaz, emin misiniz?
+settings.delete.success=Paket silindi.
+settings.delete.error=Paket silinemedi.
diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini
index 49be51a4de7d..bed92be4fd65 100644
--- a/options/locale/locale_uk-UA.ini
+++ b/options/locale/locale_uk-UA.ini
@@ -8,7 +8,6 @@ sign_out=Вийти
sign_up=Реєстрація
link_account=Прив'язати обліковий запис
register=Реєстрація
-website=Веб-сайт
version=Версія
powered_by=Працює на %s
page=Сторінка
@@ -161,7 +160,6 @@ log_root_path_helper=Файли журналу будуть записані в
optional_title=Додаткові налаштування
email_title=Налаштування Email
-smtp_host=SMTP хост
smtp_from=Відправляти Email від імені
smtp_from_helper=Електронна пошта для використання в Gіtea. Введіть звичайну електронну адресу або використовуйте формат: "Ім'я" .
mailer_user=SMTP Ім'я кристувача
@@ -2582,11 +2580,8 @@ config.queue_length=Довжина черги
config.deliver_timeout=Затримка доставки
config.skip_tls_verify=Пропустити перевірку TLS
-config.mailer_config=Конфігурація SMTP-сервера
config.mailer_enabled=Увімкнено
-config.mailer_disable_helo=Вимкнути HELO
config.mailer_name=Ім'я
-config.mailer_host=Хост
config.mailer_user=Користувач
config.mailer_use_sendmail=Використовувати Sendmail
config.mailer_sendmail_path=Шлях до Sendmail
diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini
index fb7c0e505586..fd0a6a8b4e11 100644
--- a/options/locale/locale_zh-CN.ini
+++ b/options/locale/locale_zh-CN.ini
@@ -9,7 +9,6 @@ sign_out=退出
sign_up=注册
link_account=链接账户
register=注册
-website=官方网站
version=当前版本
powered_by=Powered by %s
page=页面
@@ -20,7 +19,7 @@ active_stopwatch=活动时间跟踪器
create_new=创建…
user_profile_and_more=个人信息和配置
signed_in_as=已登录用户
-enable_javascript=使用 JavaScript能使本网站更好的工作。
+enable_javascript=使用 JavaScript 能使本网站更好的工作。
toc=目录
licenses=许可证
return_to_gitea=返回 Gitea
@@ -179,9 +178,10 @@ log_root_path_helper=日志文件将写入此目录。
optional_title=可选设置
email_title=电子邮箱设置
-smtp_host=SMTP 主机
+smtp_addr=SMTP 主机地址
+smtp_port=SMTP 端口
smtp_from=电子邮件发件人
-smtp_from_helper=电子邮件地址 Gitea 将使用。输入一个普通的电子邮件地址或使用 "名称" 格式。
+smtp_from_helper=请输入一个用于 Gitea 的电子邮件地址,或者使用完整格式:"名称"
mailer_user=SMTP 用户名
mailer_password=SMTP 密码
register_confirm=需要发电子邮件确认注册
@@ -799,6 +799,7 @@ email_notifications.enable=启用邮件通知
email_notifications.onmention=只在被提到时邮件通知
email_notifications.disable=停用邮件通知
email_notifications.submit=邮件通知设置
+email_notifications.andyourown=和您自己的通知
visibility=用户可见性
visibility.public=公开
@@ -932,6 +933,7 @@ form.name_pattern_not_allowed=仓库名称中不允许使用模式 "%s"。
need_auth=授权
migrate_options=迁移选项
migrate_service=迁移服务
+migrate_options_mirror_helper=该仓库将是一个镜像
migrate_options_lfs=迁移 LFS 文件
migrate_options_lfs_endpoint.label=LFS 网址
migrate_options_lfs_endpoint.description=迁移将尝试使用你的 Git remote 来 确定 LFS 服务器 。如果仓库 LFS 数据存储在其他位置,你还可以指定自定义网址。
@@ -1033,13 +1035,13 @@ file_view_rendered=渲染模式
file_view_raw=查看原始文件
file_permalink=永久链接
file_too_large=文件过大,无法显示。
-bidi_bad_header=`此文件包含意外的双向 Unicode 字符!`
-bidi_bad_description=`此文件包含意外的双向 Unicode 字符,其处理方式可能与下面显示的不同。 如果您是有意且合法地使用它们,可以放心地忽略此警告。 使用 Escape 按钮显示隐藏的字符。`
-bidi_bad_description_escaped=`此文件包含意外的双向 Unicode 字符。隐藏的 Unicode 字符在下面被转义。使用 Unescape 按钮来显示它们是如何渲染的。`
-unicode_header=`此文件包含隐藏的 Unicode 字符!`
-unicode_description=`该文件包含隐藏的 Unicode 字符,这些字符的处理方式可能与下面显示的不同。 如果您是有意且合法地使用它们,可以放心地忽略此警告。 使用 Escape 按钮显示隐藏的字符。`
-unicode_description_escaped=`此文件包含隐藏的 Unicode 字符。隐藏的 unicode 字符在下面被转义。请使用 Unescape 按钮来显示它们是如何渲染的。`
-line_unicode=`这一行有隐藏的 Unicode 字符`
+invisible_runes_header=`此文件包含不可见的 Unicode 字符!`
+invisible_runes_description=`这个文件包含不可见的 Unicode 字符,其处理方式可能不同于下面显示的字符。 如果您是有意且正当地使用它们,您可以安全地忽略这个警告。使用 Escape 按钮来显示隐藏的字符。
+ambiguous_runes_header=`此行包含模棱两可的 Unicode 字符!`
+ambiguous_runes_description=`此文件包含模棱两可的 Unicode 字符,这些字符可能会与您当前语言环境的其他字符混淆。 如果您是有意且正当地使用它们,您可以安全地忽略这个警告。使用 Escape 按钮来高亮这些字符。`
+invisible_runes_line=`此行含有不可见的 unicode 字符`
+ambiguous_runes_line=`此行有模棱两可的 unicode 字符`
+ambiguous_character=`%[1]c [U+%04[1]X] 容易和 %[2]c [U+%04[2]X] 混淆`
escape_control_characters=Escape
unescape_control_characters=Unescape
@@ -1060,6 +1062,7 @@ normal_view=普通视图
line=行
lines=行
+editor.add_file=添加文件
editor.new_file=新建文件
editor.upload_file=上传文件
editor.edit_file=编辑文件
@@ -1265,6 +1268,8 @@ issues.filter_milestone=里程碑筛选
issues.filter_milestone_no_select=所有里程碑
issues.filter_assignee=指派人筛选
issues.filter_assginee_no_select=所有指派成员
+issues.filter_poster=作者
+issues.filter_poster_no_select=所有作者
issues.filter_type=类型筛选
issues.filter_type.all_issues=所有工单
issues.filter_type.assigned_to_you=指派给您的
@@ -1419,6 +1424,7 @@ issues.due_date_form_remove=删除
issues.due_date_not_writer=你需要仓库写入权限来修改工单到期时间。
issues.due_date_not_set=未设置到期时间。
issues.due_date_added=于 %[2]s 设置到期时间为 %[1]s
+issues.due_date_modified=将到期日从 %[2]s 修改为 %[1]s %[3]s
issues.due_date_remove=于 %[2]s 删除了到期时间 %[1]s
issues.due_date_overdue=过期
issues.due_date_invalid=到期日期无效或超出范围。请使用 'yyyy-mm-dd' 格式。
@@ -1530,6 +1536,8 @@ pulls.remove_prefix=删除 %s 前缀
pulls.data_broken=此合并请求因为派生仓库信息缺失而中断。
pulls.files_conflicted=此合并请求有变更与目标分支冲突。
pulls.is_checking=正在进行合并冲突检测,请稍后再试。
+pulls.is_ancestor=此分支已经包含在目标分支中,没有什么可以合并。
+pulls.is_empty=此分支上的更改已经在目标分支上。这将是一个空提交。
pulls.required_status_check_failed=一些必要的检查没有成功
pulls.required_status_check_missing=缺少一些必要的检查。
pulls.required_status_check_administrator=作为管理员,您仍可合并此合并请求
@@ -2204,7 +2212,7 @@ release.stable=稳定
release.compare=比较
release.edit=编辑
release.ahead.commits=%d 次提交
-release.ahead.target=到 %s 自发布后
+release.ahead.target=在此版本发布后被加入到 %s
release.source_code=源代码
release.new_subheader=版本发布组织项目的版本。
release.edit_subheader=版本发布组织项目的版本。
@@ -2315,7 +2323,7 @@ form.create_org_not_allowed=此账号禁止创建组织
settings=组织设置
settings.options=组织
settings.full_name=组织全名
-settings.website=官方网站
+settings.website=网站
settings.location=所在地区
settings.permission=权限
settings.repoadminchangeteam=仓库管理员可以添加或移除团队的访问权限
@@ -2453,9 +2461,9 @@ dashboard.archive_cleanup=删除旧的仓库存档
dashboard.deleted_branches_cleanup=清理已删除的分支
dashboard.update_migration_poster_id=更新迁移的发表者ID
dashboard.git_gc_repos=对仓库进行垃圾回收
-dashboard.resync_all_sshkeys=使用 Gitea SSH 密钥更新'.ssh/authorized_keys' 文件。
+dashboard.resync_all_sshkeys=使用 Gitea 的 SSH 密钥更新 '.ssh/authorized_keys' 文件。
dashboard.resync_all_sshkeys.desc=(内置的 SSH 服务器不需要。)
-dashboard.resync_all_sshprincipals=使用 Gitea SSH 规则更新 '.ssh/authorized_principals' 文件。
+dashboard.resync_all_sshprincipals=使用 Gitea 的 SSH 规则更新 '.ssh/authorized_principals' 文件。
dashboard.resync_all_sshprincipals.desc=(内置的 SSH 服务器不需要。)
dashboard.resync_all_hooks=重新同步所有仓库的 pre-receive、update 和 post-receive 钩子
dashboard.reinit_missing_repos=重新初始化所有丢失的 Git 仓库存在的记录
@@ -2532,6 +2540,8 @@ users.delete_account=删除帐户
users.cannot_delete_self=你不能删除自己
users.still_own_repo=此用户仍然拥有一个或多个仓库。必须首先删除或转让这些仓库。
users.still_has_org=此用户是组织的成员。必须先从组织中删除用户。
+users.purge=清理用户
+users.purge_help=强制删除用户和用户拥有的任何仓库、组织和软件包。所有评论也将被删除。
users.still_own_packages=此用户仍然拥有一个或多个软件包。请先删除这些软件包。
users.deletion_success=用户帐户已被删除。
users.reset_2fa=重置两步验证
@@ -2788,16 +2798,19 @@ config.queue_length=队列长度
config.deliver_timeout=推送超时
config.skip_tls_verify=跳过 TLS 验证
-config.mailer_config=邮件配置
+config.mailer_config=Mailer 配置
config.mailer_enabled=启用服务
-config.mailer_disable_helo=禁用 HELO 操作
+config.mailer_enable_helo=启用HELO
config.mailer_name=任务名称
-config.mailer_host=邮件主机地址
+config.mailer_protocol=协议
+config.mailer_smtp_addr=SMTP 地址
+config.mailer_smtp_port=SMTP 端口
config.mailer_user=发送者帐号
config.mailer_use_sendmail=使用 Sendmail
config.mailer_sendmail_path=Sendmail 路径
config.mailer_sendmail_args=Sendmail 的额外参数
config.mailer_sendmail_timeout=Sendmail 超时
+config.mailer_use_dummy=Dummy
config.test_email_placeholder=电子邮址 (例如,test@example.com)
config.send_test_mail=发送测试邮件
config.test_mail_failed=发送测试邮件至 '%s' 时失败:%v
@@ -2882,6 +2895,7 @@ monitor.queue.nopool.title=没有工作者池
monitor.queue.nopool.desc=此队列包装其它队列,本身没有工作者池。
monitor.queue.wrapped.desc=一个包装队列包装一个启动缓慢队列,缓存队列请求到 channel 中。它本身没有一个工作者池。
monitor.queue.persistable-channel.desc=一个 persistable-channel 队列包装2个队列,一个 channel 队列拥有自己的工作者池,一个 level 队列用于永久存储。它没有自己的工作者池。
+monitor.queue.flush=Flush worker
monitor.queue.pool.timeout=超时
monitor.queue.pool.addworkers.title=新增工作者
monitor.queue.pool.addworkers.submit=新增工作者
@@ -3034,6 +3048,7 @@ title=软件包
desc=管理仓库软件包。
empty=还没有软件包。
empty.documentation=关于软件包注册中心的更多信息,请参阅 文档 。
+empty.repo=您上传了一个包,但没有显示在这里吗?转到 包设置 并将其链接到这个仓库中。
filter.type=类型
filter.type.all=所有
filter.no_result=您的过滤器没有产生任何结果。
@@ -3099,6 +3114,10 @@ npm.dependencies.development=开发依赖
npm.dependencies.peer=Peer 依赖
npm.dependencies.optional=可选依赖
npm.details.tag=标签
+pub.install=要使用 Dart 安装软件包,请运行以下命令:
+pub.documentation=关于 Pub 注册中心的信息,请参阅 文档 。
+pub.details.repository_site=仓库站点
+pub.details.documentation_site=文档站点
pypi.requires=需要 Python
pypi.install=要使用 pip 安装软件包,请运行以下命令:
pypi.documentation=关于 PyPI 注册中心的信息,请参阅 文档 。
diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini
index c6ea7ce67351..18168c1db904 100644
--- a/options/locale/locale_zh-HK.ini
+++ b/options/locale/locale_zh-HK.ini
@@ -6,7 +6,6 @@ sign_in=登入
sign_out=登出
link_account=連結帳戶
register=註冊
-website=網站
version=版本
page=頁面
template=樣板
@@ -64,7 +63,6 @@ repo_path=儲存庫的根目錄
log_root_path=日誌路徑
optional_title=可選設定
-smtp_host=SMTP 主機
federated_avatar_lookup_popup=開啟聯合頭像查詢並使用基於開放源碼的 libravatar 服務
enable_captcha_popup=要求在用戶註冊時輸入驗證碼
admin_password=管理員密碼
@@ -760,9 +758,7 @@ config.deliver_timeout=推送超時
config.skip_tls_verify=略過 TLS 驗證
config.mailer_enabled=啟用服務
-config.mailer_disable_helo=禁用 HELO 操作
config.mailer_name=發送者名稱
-config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.oauth_config=社交帳號設定
diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini
index 8d89c51a1d20..47f8ffcdf68e 100644
--- a/options/locale/locale_zh-TW.ini
+++ b/options/locale/locale_zh-TW.ini
@@ -9,7 +9,6 @@ sign_out=登出
sign_up=註冊
link_account=連結帳戶
register=註冊
-website=網站
version=版本
powered_by=技術提供: %s
page=頁面
@@ -179,7 +178,6 @@ log_root_path_helper=日誌檔將寫入此目錄。
optional_title=可選設定
email_title=電子郵件設定
-smtp_host=SMTP 主機
smtp_from=電子郵件寄件者
smtp_from_helper=Gitea 將會使用的電子信箱,直接輸入電子信箱或使用「"名稱" 」的格式。
mailer_user=SMTP 帳號
@@ -1033,13 +1031,6 @@ file_view_rendered=檢視渲染圖
file_view_raw=查看原始文件
file_permalink=永久連結
file_too_large=檔案太大,無法顯示。
-bidi_bad_header=`此檔案含有未預期的 Bidirectional Unicode 字元!`
-bidi_bad_description=`此檔案含有未預期的 Bidirectional Unicode 字元,這些字元的處理方式可能和下面呈現的不同。若您是有意且合理的使用,您可以放心地忽略此警告。使用 Escape 按鈕顯示隱藏的字元。`
-bidi_bad_description_escaped=`此檔案含有未預期的 Bidirectional Unicode 字元。隱藏的 Unicode 字元已在下面被跳脫 (Escaped)。使用 Unescape 按鈕以顯示它們呈現的樣子。`
-unicode_header=`此檔案含有隱藏的 Unicode 字元!`
-unicode_description=`此檔案含有隱藏的 Unicode 字元,這些字元的處理方式可能和下面呈現的不同。若您是有意且合理的使用,您可以放心地忽略此警告。使用 Escape 按鈕顯示隱藏的字元。`
-unicode_description_escaped=`此檔案含有隱藏的 Unicode 字元。隱藏的 Unicode 字元已在下面被跳脫 (Escaped)。使用 Unescape 按鈕以顯示它們呈現的樣子。`
-line_unicode=`這一行有隱藏的 Unicode 字元`
escape_control_characters=Escape
unescape_control_characters=Unescape
@@ -2788,11 +2779,8 @@ config.queue_length=佇列長度
config.deliver_timeout=傳送逾時
config.skip_tls_verify=略過 TLS 驗證
-config.mailer_config=SMTP 組態
config.mailer_enabled=啟用服務
-config.mailer_disable_helo=停用 HELO 操作
config.mailer_name=發送者名稱
-config.mailer_host=郵件主機地址
config.mailer_user=發送者帳號
config.mailer_use_sendmail=使用 Sendmail
config.mailer_sendmail_path=Sendmail 路徑
diff --git a/package-lock.json b/package-lock.json
index 8ebff450e2a5..aabbd84fd9bc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,8 @@
"license": "MIT",
"dependencies": {
"@claviska/jquery-minicolors": "2.3.6",
- "@primer/octicons": "17.3.0",
+ "@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
+ "@primer/octicons": "17.4.0",
"add-asset-webpack-plugin": "2.0.1",
"css-loader": "6.7.1",
"dropzone": "6.0.0-beta.2",
@@ -28,7 +29,7 @@
"monaco-editor-webpack-plugin": "7.0.1",
"pretty-ms": "8.0.0",
"sortablejs": "1.15.0",
- "swagger-ui-dist": "4.13.0",
+ "swagger-ui-dist": "4.13.2",
"tippy.js": "6.3.7",
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
@@ -37,22 +38,22 @@
"vue-calendar-heatmap": "0.8.4",
"vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14",
- "webpack": "5.73.0",
+ "webpack": "5.74.0",
"webpack-cli": "4.10.0",
- "workbox-routing": "6.5.3",
- "workbox-strategies": "6.5.3",
+ "workbox-routing": "6.5.4",
+ "workbox-strategies": "6.5.4",
"worker-loader": "3.0.8",
"wrap-ansi": "8.0.1"
},
"devDependencies": {
"@happy-dom/jest-environment": "6.0.4",
- "@stoplight/spectral-cli": "6.4.1",
- "eslint": "8.20.0",
+ "@stoplight/spectral-cli": "6.5.0",
+ "eslint": "8.21.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-sonarjs": "0.13.0",
+ "eslint-plugin-sonarjs": "0.14.0",
"eslint-plugin-unicorn": "43.0.2",
- "eslint-plugin-vue": "9.2.0",
+ "eslint-plugin-vue": "9.3.0",
"jest": "28.1.3",
"jest-extended": "3.0.1",
"markdownlint-cli": "0.32.1",
@@ -60,7 +61,7 @@
"stylelint": "14.9.1",
"stylelint-config-standard": "26.0.0",
"svgo": "2.8.0",
- "updates": "13.1.2"
+ "updates": "13.1.4"
},
"engines": {
"node": ">= 14.0.0"
@@ -107,21 +108,21 @@
}
},
"node_modules/@babel/core": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
- "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+ "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
"dev": true,
"dependencies": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.18.9",
+ "@babel/generator": "^7.18.10",
"@babel/helper-compilation-targets": "^7.18.9",
"@babel/helper-module-transforms": "^7.18.9",
"@babel/helpers": "^7.18.9",
- "@babel/parser": "^7.18.9",
- "@babel/template": "^7.18.6",
- "@babel/traverse": "^7.18.9",
- "@babel/types": "^7.18.9",
+ "@babel/parser": "^7.18.10",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.18.10",
+ "@babel/types": "^7.18.10",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -146,12 +147,12 @@
}
},
"node_modules/@babel/generator": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
- "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz",
+ "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==",
"dev": true,
"dependencies": {
- "@babel/types": "^7.18.9",
+ "@babel/types": "^7.18.10",
"@jridgewell/gen-mapping": "^0.3.2",
"jsesc": "^2.5.1"
},
@@ -298,6 +299,15 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+ "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+ "dev": true,
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
"node_modules/@babel/helper-validator-identifier": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -416,9 +426,9 @@
}
},
"node_modules/@babel/parser": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
- "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz",
+ "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==",
"dev": true,
"bin": {
"parser": "bin/babel-parser.js"
@@ -601,33 +611,33 @@
}
},
"node_modules/@babel/template": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
- "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+ "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.18.6",
- "@babel/types": "^7.18.6"
+ "@babel/parser": "^7.18.10",
+ "@babel/types": "^7.18.10"
},
"engines": {
"node": ">=6.9.0"
}
},
"node_modules/@babel/traverse": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
- "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz",
+ "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==",
"dev": true,
"dependencies": {
"@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.18.9",
+ "@babel/generator": "^7.18.10",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.18.9",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.18.9",
- "@babel/types": "^7.18.9",
+ "@babel/parser": "^7.18.10",
+ "@babel/types": "^7.18.10",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -645,11 +655,12 @@
}
},
"node_modules/@babel/types": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
- "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+ "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
"dev": true,
"dependencies": {
+ "@babel/helper-string-parser": "^7.18.10",
"@babel/helper-validator-identifier": "^7.18.6",
"to-fast-properties": "^2.0.0"
},
@@ -701,6 +712,21 @@
"node": ">=10.0.0"
}
},
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz",
+ "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==",
+ "cpu": [
+ "loong64"
+ ],
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=12"
+ }
+ },
"node_modules/@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -758,9 +784,9 @@
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+ "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -771,6 +797,16 @@
"node": ">=10.10.0"
}
},
+ "node_modules/@humanwhocodes/gitignore-to-minimatch": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+ "dev": true,
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
"node_modules/@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -867,15 +903,6 @@
"node": ">=8"
}
},
- "node_modules/@istanbuljs/load-nyc-config/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -1636,6 +1663,55 @@
"jsep": "^0.4.0||^1.0.0"
}
},
+ "node_modules/@mcaptcha/core-glue": {
+ "version": "0.1.0-alpha-3",
+ "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz",
+ "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "http://mcaptcha.org/donate"
+ },
+ {
+ "type": "liberapay",
+ "url": "https://liberapay.com/mcaptcha"
+ },
+ {
+ "type": "individual",
+ "url": "http://batsense.net/donate"
+ },
+ {
+ "type": "liberapay",
+ "url": "https://liberapay.com/realaravinth"
+ }
+ ]
+ },
+ "node_modules/@mcaptcha/vanilla-glue": {
+ "version": "0.1.0-alpha-2",
+ "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz",
+ "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==",
+ "funding": [
+ {
+ "type": "individual",
+ "url": "http://mcaptcha.org/donate"
+ },
+ {
+ "type": "liberapay",
+ "url": "https://liberapay.com/mcaptcha"
+ },
+ {
+ "type": "individual",
+ "url": "http://batsense.net/donate"
+ },
+ {
+ "type": "liberapay",
+ "url": "https://liberapay.com/realaravinth"
+ }
+ ],
+ "dependencies": {
+ "@mcaptcha/core-glue": "^0.1.0-alpha-3"
+ }
+ },
"node_modules/@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -1678,9 +1754,9 @@
}
},
"node_modules/@primer/octicons": {
- "version": "17.3.0",
- "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.3.0.tgz",
- "integrity": "sha512-4zPwwloYWdR6RznMafV7Fsw3n2CeDPp/+qEIQbaX/tBbPY1KmU0OAXmhRfhD5AzgB5kdV1aQ7KnQr1GeQXl9Dg==",
+ "version": "17.4.0",
+ "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz",
+ "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==",
"dependencies": {
"object-assign": "^4.1.1"
}
@@ -1730,9 +1806,9 @@
"dev": true
},
"node_modules/@sinclair/typebox": {
- "version": "0.24.20",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.20.tgz",
- "integrity": "sha512-kVaO5aEFZb33nPMTZBxiPEkY+slxiPtqC7QX8f9B3eGOMBvEfuMfxp9DSTTCsRJPumPKjrge4yagyssO4q6qzQ==",
+ "version": "0.24.26",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz",
+ "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==",
"dev": true
},
"node_modules/@sinonjs/commons": {
@@ -1857,9 +1933,9 @@
}
},
"node_modules/@stoplight/spectral-cli": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.4.1.tgz",
- "integrity": "sha512-l5nWXy/6YEyk51VVrOurhupVScIqfK0ra8yIRSli+gnW5Kf5Nfw5PLci5GceQGaM5WE+wmqZ/iY95yOVFwHc+A==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz",
+ "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==",
"dev": true,
"dependencies": {
"@rollup/plugin-commonjs": "^20.0.0",
@@ -1922,9 +1998,9 @@
}
},
"node_modules/@stoplight/spectral-core": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.12.3.tgz",
- "integrity": "sha512-+PhVzTD8q6kUZw4BcbM+ibVaH5/ELryKt5tlLitA8SJIaJ+5/9ZKaGN0AV3ExZQZGYvXwucPOQuJKYZYKA6mWg==",
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz",
+ "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==",
"dev": true,
"dependencies": {
"@stoplight/better-ajv-errors": "1.0.1",
@@ -1935,11 +2011,13 @@
"@stoplight/spectral-ref-resolver": "^1.0.0",
"@stoplight/spectral-runtime": "^1.0.0",
"@stoplight/types": "~13.2.0",
+ "@types/es-aggregate-error": "^1.0.2",
"@types/json-schema": "^7.0.11",
"ajv": "^8.6.0",
"ajv-errors": "~3.0.0",
"ajv-formats": "~2.1.0",
"blueimp-md5": "2.18.0",
+ "es-aggregate-error": "^1.0.7",
"jsonpath-plus": "6.0.1",
"lodash": "~4.17.21",
"lodash.topath": "^4.5.2",
@@ -1998,9 +2076,9 @@
}
},
"node_modules/@stoplight/spectral-functions": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.6.1.tgz",
- "integrity": "sha512-f4cFtbI35bQtY0t4fYhKtS+/nMU3UsAeFlqm4tARGGG5WjOv4ieCFNFbgodKNiO3F4O+syMEjVQuXlBNPuY7jw==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz",
+ "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==",
"dev": true,
"dependencies": {
"@stoplight/better-ajv-errors": "1.0.1",
@@ -2068,12 +2146,12 @@
}
},
"node_modules/@stoplight/spectral-ruleset-bundler": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.0.tgz",
- "integrity": "sha512-6Tif7GQL18F0LN1+FhEmhFWgE/TiWudb/pFl4DC7oS1QRoutB7QJPqIfVFSmteToPidxlrIbC6VAXSyEhlpDVQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.1.tgz",
+ "integrity": "sha512-TWjLFYBor1s/0v3xXwdVzzyUVu7ez2vYVNN4RMbJG7HIZgYW8MMVx4AVg5Eo1ZgLTkj/aeaoAOjIP7t+u6IBUg==",
"dev": true,
"dependencies": {
- "@rollup/plugin-commonjs": "^21.0.1",
+ "@rollup/plugin-commonjs": "~22.0.0",
"@stoplight/path": "1.3.2",
"@stoplight/spectral-core": ">=1",
"@stoplight/spectral-formats": ">=1",
@@ -2086,7 +2164,7 @@
"@stoplight/types": "^12.3.0",
"@types/node": "*",
"pony-cause": "1.1.1",
- "rollup": "~2.67.0",
+ "rollup": "~2.75.5",
"tslib": "^2.3.1",
"validate-npm-package-name": "3.0.0"
},
@@ -2095,9 +2173,9 @@
}
},
"node_modules/@stoplight/spectral-ruleset-bundler/node_modules/@rollup/plugin-commonjs": {
- "version": "21.1.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz",
- "integrity": "sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==",
+ "version": "22.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz",
+ "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==",
"dev": true,
"dependencies": {
"@rollup/pluginutils": "^3.1.0",
@@ -2109,16 +2187,16 @@
"resolve": "^1.17.0"
},
"engines": {
- "node": ">= 8.0.0"
+ "node": ">= 12.0.0"
},
"peerDependencies": {
- "rollup": "^2.38.3"
+ "rollup": "^2.68.0"
}
},
"node_modules/@stoplight/spectral-ruleset-bundler/node_modules/rollup": {
- "version": "2.67.3",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.3.tgz",
- "integrity": "sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==",
+ "version": "2.75.7",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz",
+ "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==",
"dev": true,
"bin": {
"rollup": "dist/bin/rollup"
@@ -2165,9 +2243,9 @@
}
},
"node_modules/@stoplight/spectral-rulesets": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.0.tgz",
- "integrity": "sha512-0zFbxIuoWmGrkl2txOuaEDF8o6aoKDpMAYOG2oDfmmX9FhXX3c3ivIy80hyb2tMKkIYuqqx/zwIiOuww5S8iUA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz",
+ "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==",
"dev": true,
"dependencies": {
"@asyncapi/specs": "^2.14.0",
@@ -2335,6 +2413,15 @@
"@types/node": "*"
}
},
+ "node_modules/@types/es-aggregate-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz",
+ "integrity": "sha512-erqUpFXksaeR2kejKnhnjZjbFxUpGZx4Z7ydNL9ie8tEhXPiZTsLeUDJ6aR1F8j5wWUAtOAQWUqkc7givBJbBA==",
+ "dev": true,
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
"node_modules/@types/eslint": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz",
@@ -2423,9 +2510,9 @@
"dev": true
},
"node_modules/@types/node": {
- "version": "18.0.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
- "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw=="
+ "version": "18.6.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+ "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg=="
},
"node_modules/@types/normalize-package-data": {
"version": "2.4.1",
@@ -2440,9 +2527,9 @@
"dev": true
},
"node_modules/@types/prettier": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
- "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz",
+ "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
"dev": true
},
"node_modules/@types/qs": {
@@ -2726,9 +2813,9 @@
}
},
"node_modules/acorn": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
- "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
"bin": {
"acorn": "bin/acorn"
},
@@ -3177,9 +3264,9 @@
}
},
"node_modules/browserslist": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz",
- "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+ "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
"funding": [
{
"type": "opencollective",
@@ -3191,10 +3278,10 @@
}
],
"dependencies": {
- "caniuse-lite": "^1.0.30001366",
- "electron-to-chromium": "^1.4.188",
+ "caniuse-lite": "^1.0.30001370",
+ "electron-to-chromium": "^1.4.202",
"node-releases": "^2.0.6",
- "update-browserslist-db": "^1.0.4"
+ "update-browserslist-db": "^1.0.5"
},
"bin": {
"browserslist": "cli.js"
@@ -3293,9 +3380,9 @@
}
},
"node_modules/caniuse-lite": {
- "version": "1.0.30001367",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz",
- "integrity": "sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw==",
+ "version": "1.0.30001373",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+ "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ==",
"funding": [
{
"type": "opencollective",
@@ -3454,9 +3541,9 @@
}
},
"node_modules/codemirror": {
- "version": "5.65.6",
- "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.6.tgz",
- "integrity": "sha512-zNihMSMoDxK9Gqv9oEyDT8oM51rcRrQ+IEo2zyS48gJByBq5Fj8XuNEguMra+MuIOuh6lkpnLUJeL70DoTt6yw=="
+ "version": "5.65.7",
+ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz",
+ "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A=="
},
"node_modules/codemirror-spell-checker": {
"version": "1.1.2",
@@ -3512,11 +3599,12 @@
}
},
"node_modules/commander": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
+ "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
+ "dev": true,
"engines": {
- "node": ">= 10"
+ "node": "^12.20.0 || >=14"
}
},
"node_modules/commondir": {
@@ -3909,6 +3997,14 @@
"node": ">=12"
}
},
+ "node_modules/d3-dsv/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/d3-ease": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
@@ -4652,6 +4748,15 @@
"url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
}
},
+ "node_modules/dom-serializer/node_modules/entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true,
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
"node_modules/domelementtype": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
@@ -4725,9 +4830,9 @@
}
},
"node_modules/electron-to-chromium": {
- "version": "1.4.195",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.195.tgz",
- "integrity": "sha512-vefjEh0sk871xNmR5whJf9TEngX+KTKS3hOHpjoMpauKkwlGwtMz1H8IaIjAT/GNnX0TbGwAdmVoXCAzXf+PPg=="
+ "version": "1.4.210",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+ "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ=="
},
"node_modules/emittery": {
"version": "0.10.2",
@@ -4767,10 +4872,13 @@
}
},
"node_modules/entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"dev": true,
+ "engines": {
+ "node": ">=0.12"
+ },
"funding": {
"url": "https://github.com/fb55/entities?sponsor=1"
}
@@ -4850,6 +4958,27 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es-aggregate-error": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.8.tgz",
+ "integrity": "sha512-AKUb5MKLWMozPlFRHOKqWD7yta5uaEhH21qwtnf6FlKjNjTJOoqFi0/G14+FfSkIQhhu6X68Af4xgRC6y8qG4A==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5",
+ "function-bind": "^1.1.1",
+ "functions-have-names": "^1.2.3",
+ "get-intrinsic": "^1.1.1",
+ "globalthis": "^1.0.2",
+ "has-property-descriptors": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/es-module-lexer": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
@@ -4882,9 +5011,9 @@
}
},
"node_modules/esbuild": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.49.tgz",
- "integrity": "sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz",
+ "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==",
"hasInstallScript": true,
"bin": {
"esbuild": "bin/esbuild"
@@ -4893,32 +5022,33 @@
"node": ">=12"
},
"optionalDependencies": {
- "esbuild-android-64": "0.14.49",
- "esbuild-android-arm64": "0.14.49",
- "esbuild-darwin-64": "0.14.49",
- "esbuild-darwin-arm64": "0.14.49",
- "esbuild-freebsd-64": "0.14.49",
- "esbuild-freebsd-arm64": "0.14.49",
- "esbuild-linux-32": "0.14.49",
- "esbuild-linux-64": "0.14.49",
- "esbuild-linux-arm": "0.14.49",
- "esbuild-linux-arm64": "0.14.49",
- "esbuild-linux-mips64le": "0.14.49",
- "esbuild-linux-ppc64le": "0.14.49",
- "esbuild-linux-riscv64": "0.14.49",
- "esbuild-linux-s390x": "0.14.49",
- "esbuild-netbsd-64": "0.14.49",
- "esbuild-openbsd-64": "0.14.49",
- "esbuild-sunos-64": "0.14.49",
- "esbuild-windows-32": "0.14.49",
- "esbuild-windows-64": "0.14.49",
- "esbuild-windows-arm64": "0.14.49"
+ "@esbuild/linux-loong64": "0.14.53",
+ "esbuild-android-64": "0.14.53",
+ "esbuild-android-arm64": "0.14.53",
+ "esbuild-darwin-64": "0.14.53",
+ "esbuild-darwin-arm64": "0.14.53",
+ "esbuild-freebsd-64": "0.14.53",
+ "esbuild-freebsd-arm64": "0.14.53",
+ "esbuild-linux-32": "0.14.53",
+ "esbuild-linux-64": "0.14.53",
+ "esbuild-linux-arm": "0.14.53",
+ "esbuild-linux-arm64": "0.14.53",
+ "esbuild-linux-mips64le": "0.14.53",
+ "esbuild-linux-ppc64le": "0.14.53",
+ "esbuild-linux-riscv64": "0.14.53",
+ "esbuild-linux-s390x": "0.14.53",
+ "esbuild-netbsd-64": "0.14.53",
+ "esbuild-openbsd-64": "0.14.53",
+ "esbuild-sunos-64": "0.14.53",
+ "esbuild-windows-32": "0.14.53",
+ "esbuild-windows-64": "0.14.53",
+ "esbuild-windows-arm64": "0.14.53"
}
},
"node_modules/esbuild-android-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz",
- "integrity": "sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz",
+ "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==",
"cpu": [
"x64"
],
@@ -4931,9 +5061,9 @@
}
},
"node_modules/esbuild-android-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz",
- "integrity": "sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz",
+ "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==",
"cpu": [
"arm64"
],
@@ -4946,9 +5076,9 @@
}
},
"node_modules/esbuild-darwin-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz",
- "integrity": "sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz",
+ "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==",
"cpu": [
"x64"
],
@@ -4961,9 +5091,9 @@
}
},
"node_modules/esbuild-darwin-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz",
- "integrity": "sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz",
+ "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==",
"cpu": [
"arm64"
],
@@ -4976,9 +5106,9 @@
}
},
"node_modules/esbuild-freebsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz",
- "integrity": "sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz",
+ "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==",
"cpu": [
"x64"
],
@@ -4991,9 +5121,9 @@
}
},
"node_modules/esbuild-freebsd-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz",
- "integrity": "sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz",
+ "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==",
"cpu": [
"arm64"
],
@@ -5006,9 +5136,9 @@
}
},
"node_modules/esbuild-linux-32": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz",
- "integrity": "sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz",
+ "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==",
"cpu": [
"ia32"
],
@@ -5021,9 +5151,9 @@
}
},
"node_modules/esbuild-linux-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz",
- "integrity": "sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz",
+ "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==",
"cpu": [
"x64"
],
@@ -5036,9 +5166,9 @@
}
},
"node_modules/esbuild-linux-arm": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz",
- "integrity": "sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz",
+ "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==",
"cpu": [
"arm"
],
@@ -5051,9 +5181,9 @@
}
},
"node_modules/esbuild-linux-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz",
- "integrity": "sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz",
+ "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==",
"cpu": [
"arm64"
],
@@ -5066,9 +5196,9 @@
}
},
"node_modules/esbuild-linux-mips64le": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz",
- "integrity": "sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz",
+ "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==",
"cpu": [
"mips64el"
],
@@ -5081,9 +5211,9 @@
}
},
"node_modules/esbuild-linux-ppc64le": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz",
- "integrity": "sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz",
+ "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==",
"cpu": [
"ppc64"
],
@@ -5096,9 +5226,9 @@
}
},
"node_modules/esbuild-linux-riscv64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz",
- "integrity": "sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz",
+ "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==",
"cpu": [
"riscv64"
],
@@ -5111,9 +5241,9 @@
}
},
"node_modules/esbuild-linux-s390x": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz",
- "integrity": "sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz",
+ "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==",
"cpu": [
"s390x"
],
@@ -5145,9 +5275,9 @@
}
},
"node_modules/esbuild-netbsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz",
- "integrity": "sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz",
+ "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==",
"cpu": [
"x64"
],
@@ -5160,9 +5290,9 @@
}
},
"node_modules/esbuild-openbsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz",
- "integrity": "sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz",
+ "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==",
"cpu": [
"x64"
],
@@ -5175,9 +5305,9 @@
}
},
"node_modules/esbuild-sunos-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz",
- "integrity": "sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz",
+ "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==",
"cpu": [
"x64"
],
@@ -5190,9 +5320,9 @@
}
},
"node_modules/esbuild-windows-32": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz",
- "integrity": "sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz",
+ "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==",
"cpu": [
"ia32"
],
@@ -5205,9 +5335,9 @@
}
},
"node_modules/esbuild-windows-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz",
- "integrity": "sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz",
+ "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==",
"cpu": [
"x64"
],
@@ -5220,9 +5350,9 @@
}
},
"node_modules/esbuild-windows-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz",
- "integrity": "sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz",
+ "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==",
"cpu": [
"arm64"
],
@@ -5348,13 +5478,14 @@
}
},
"node_modules/eslint": {
- "version": "8.20.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
- "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+ "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
"dev": true,
"dependencies": {
"@eslint/eslintrc": "^1.3.0",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@humanwhocodes/config-array": "^0.10.4",
+ "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -5364,14 +5495,17 @@
"eslint-scope": "^7.1.1",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.2",
+ "espree": "^9.3.3",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1",
"globals": "^13.15.0",
+ "globby": "^11.1.0",
+ "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@@ -5440,6 +5574,73 @@
"ms": "^2.1.1"
}
},
+ "node_modules/eslint-module-utils/node_modules/find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "dependencies": {
+ "locate-path": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "dependencies": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "dependencies": {
+ "p-try": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "dependencies": {
+ "p-limit": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/eslint-module-utils/node_modules/path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true,
+ "engines": {
+ "node": ">=4"
+ }
+ },
"node_modules/eslint-plugin-import": {
"version": "2.26.0",
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz",
@@ -5504,9 +5705,9 @@
}
},
"node_modules/eslint-plugin-sonarjs": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.13.0.tgz",
- "integrity": "sha512-t3m7ta0EspzDxSOZh3cEOJIJVZgN/TlJYaBGnQlK6W/PZNbWep8q4RQskkJkA7/zwNpX0BaoEOSUUrqaADVoqA==",
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz",
+ "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==",
"dev": true,
"engines": {
"node": ">=12"
@@ -5547,9 +5748,9 @@
}
},
"node_modules/eslint-plugin-vue": {
- "version": "9.2.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.2.0.tgz",
- "integrity": "sha512-W2hc+NUXoce8sZtWgZ45miQTy6jNyuSdub5aZ1IBune4JDeAyzucYX0TzkrQ1jMO52sNUDYlCIHDoaNePe0p5g==",
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz",
+ "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==",
"dev": true,
"dependencies": {
"eslint-utils": "^3.0.0",
@@ -5639,17 +5840,20 @@
"dev": true
},
"node_modules/espree": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
- "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+ "version": "9.3.3",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+ "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
"dev": true,
"dependencies": {
- "acorn": "^8.7.1",
+ "acorn": "^8.8.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.3.0"
},
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
}
},
"node_modules/esprima": {
@@ -5900,9 +6104,9 @@
"dev": true
},
"node_modules/fastest-levenshtein": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.14.tgz",
- "integrity": "sha512-tFfWHjnuUfKE186Tfgr+jtaFc0mZTApEgKDOeyN+FwOqRkO/zK/3h1AiRd8u8CY53owL3CUmGr/oI9p/RdyLTA==",
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
"engines": {
"node": ">= 4.9.1"
}
@@ -5957,15 +6161,19 @@
}
},
"node_modules/find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"dependencies": {
- "locate-path": "^2.0.0"
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/flat-cache": {
@@ -6160,12 +6368,12 @@
"dev": true
},
"node_modules/get-stdin": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
- "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
"dev": true,
"engines": {
- "node": ">=10"
+ "node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
@@ -6278,6 +6486,12 @@
"node": ">=6"
}
},
+ "node_modules/global-prefix/node_modules/ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
"node_modules/global-prefix/node_modules/which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -6291,9 +6505,9 @@
}
},
"node_modules/globals": {
- "version": "13.16.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
- "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+ "version": "13.17.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+ "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -6305,6 +6519,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -6336,6 +6565,12 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
+ "node_modules/grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
+ },
"node_modules/graphlib": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
@@ -6688,10 +6923,13 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
- "dev": true
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
+ "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
+ "dev": true,
+ "engines": {
+ "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
+ }
},
"node_modules/internal-slot": {
"version": "1.0.3",
@@ -6764,15 +7002,18 @@
}
},
"node_modules/is-builtin-module": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
- "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+ "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
"dev": true,
"dependencies": {
- "builtin-modules": "^3.0.0"
+ "builtin-modules": "^3.3.0"
},
"engines": {
"node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/is-callable": {
@@ -8883,16 +9124,18 @@
}
},
"node_modules/locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"dependencies": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
+ "p-locate": "^5.0.0"
},
"engines": {
- "node": ">=4"
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/lodash": {
@@ -9031,18 +9274,6 @@
"markdown-it": "bin/markdown-it.js"
}
},
- "node_modules/markdown-it/node_modules/entities": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
- "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
- "dev": true,
- "engines": {
- "node": ">=0.12"
- },
- "funding": {
- "url": "https://github.com/fb55/entities?sponsor=1"
- }
- },
"node_modules/markdownlint": {
"version": "0.26.1",
"resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.26.1.tgz",
@@ -9088,27 +9319,6 @@
"balanced-match": "^1.0.0"
}
},
- "node_modules/markdownlint-cli/node_modules/commander": {
- "version": "9.4.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
- "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
- "dev": true,
- "engines": {
- "node": "^12.20.0 || >=14"
- }
- },
- "node_modules/markdownlint-cli/node_modules/get-stdin": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
- "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
"node_modules/markdownlint-cli/node_modules/glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@@ -9723,36 +9933,18 @@
}
},
"node_modules/p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"dependencies": {
- "p-limit": "^1.1.0"
+ "p-limit": "^3.0.2"
},
"engines": {
- "node": ">=4"
- }
- },
- "node_modules/p-locate/node_modules/p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "dependencies": {
- "p-try": "^1.0.0"
+ "node": ">=10"
},
- "engines": {
- "node": ">=4"
- }
- },
- "node_modules/p-locate/node_modules/p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
- "dev": true,
- "engines": {
- "node": ">=4"
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/p-try": {
@@ -9853,12 +10045,11 @@
}
},
"node_modules/path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
- "dev": true,
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
"engines": {
- "node": ">=4"
+ "node": ">=8"
}
},
"node_modules/path-is-absolute": {
@@ -9984,14 +10175,6 @@
"node": ">=8"
}
},
- "node_modules/pkg-dir/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/pluralize": {
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz",
@@ -10466,15 +10649,6 @@
"node": ">=8"
}
},
- "node_modules/read-pkg-up/node_modules/path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
"node_modules/read-pkg-up/node_modules/type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -10681,9 +10855,9 @@
"integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
},
"node_modules/rollup": {
- "version": "2.77.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
- "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+ "version": "2.77.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+ "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
"dev": true,
"peer": true,
"bin": {
@@ -10711,15 +10885,6 @@
"run-con": "cli.js"
}
},
- "node_modules/run-con/node_modules/ini": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
- "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
- "dev": true,
- "engines": {
- "node": "^12.13.0 || ^14.15.0 || >=16.0.0"
- }
- },
"node_modules/run-parallel": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -11339,6 +11504,18 @@
"integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
"dev": true
},
+ "node_modules/stylelint/node_modules/get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "dev": true,
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
"node_modules/stylelint/node_modules/resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -11421,10 +11598,19 @@
"node": ">=10.13.0"
}
},
+ "node_modules/svgo/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/swagger-ui-dist": {
- "version": "4.13.0",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.0.tgz",
- "integrity": "sha512-5yqhkUU9uV5oT/MTMBeSgDGI0Vx6eCOU43AszQBs88poI8OB1v+FoXEFHv+NaBbEfTkXCMWlAJrH6iWyDzLETQ=="
+ "version": "4.13.2",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz",
+ "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A=="
},
"node_modules/sync-request": {
"version": "6.1.0",
@@ -11814,9 +12000,9 @@
"dev": true
},
"node_modules/typo-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.1.tgz",
- "integrity": "sha512-bTGLjbD3WqZDR3CgEFkyi9Q/SS2oM29ipXrWfDb4M74ea69QwKAECVceYpaBu0GfdnASMg9Qfl67ttB23nePHg=="
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz",
+ "integrity": "sha512-C7pYBQK17EjSg8tVNY91KHdUt5Nf6FMJ+c3js076quPmBML57PmNMzAcIq/2kf/hSYtFABNDIYNYlJRl5BJhGw=="
},
"node_modules/uc.micro": {
"version": "1.0.6",
@@ -11888,9 +12074,9 @@
}
},
"node_modules/updates": {
- "version": "13.1.2",
- "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.2.tgz",
- "integrity": "sha512-wixXdKufbYwxKFMqWmkjnf6vlkZ8Lpx8fWYFrkxawNO9j7xlGQHCtbqW7LHkl/+tl57fFlvgvQ5dAIrseqk3Qw==",
+ "version": "13.1.4",
+ "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.4.tgz",
+ "integrity": "sha512-s8FKpHpREDoIbd1JDcEvsdf+wenhcQjrZK8v7OTIW69kozPttm6rW84Mm/LFouiDVYgaubY3us7sZlRUiGVx4Q==",
"dev": true,
"bin": {
"updates": "bin/updates.js"
@@ -12181,20 +12367,20 @@
}
},
"node_modules/webpack": {
- "version": "5.73.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz",
- "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==",
+ "version": "5.74.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
+ "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
"dependencies": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^0.0.51",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
- "acorn": "^8.4.1",
+ "acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.9.3",
+ "enhanced-resolve": "^5.10.0",
"es-module-lexer": "^0.9.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
@@ -12207,7 +12393,7 @@
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
- "watchpack": "^2.3.1",
+ "watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
"bin": {
@@ -12272,6 +12458,14 @@
}
}
},
+ "node_modules/webpack-cli/node_modules/commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "engines": {
+ "node": ">= 10"
+ }
+ },
"node_modules/webpack-merge": {
"version": "5.8.0",
"resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz",
@@ -12462,24 +12656,24 @@
}
},
"node_modules/workbox-core": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.3.tgz",
- "integrity": "sha512-Bb9ey5n/M9x+l3fBTlLpHt9ASTzgSGj6vxni7pY72ilB/Pb3XtN+cZ9yueboVhD5+9cNQrC9n/E1fSrqWsUz7Q=="
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz",
+ "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q=="
},
"node_modules/workbox-routing": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.3.tgz",
- "integrity": "sha512-DFjxcuRAJjjt4T34RbMm3MCn+xnd36UT/2RfPRfa8VWJGItGJIn7tG+GwVTdHmvE54i/QmVTJepyAGWtoLPTmg==",
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz",
+ "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==",
"dependencies": {
- "workbox-core": "6.5.3"
+ "workbox-core": "6.5.4"
}
},
"node_modules/workbox-strategies": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.3.tgz",
- "integrity": "sha512-MgmGRrDVXs7rtSCcetZgkSZyMpRGw8HqL2aguszOc3nUmzGZsT238z/NN9ZouCxSzDu3PQ3ZSKmovAacaIhu1w==",
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz",
+ "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==",
"dependencies": {
- "workbox-core": "6.5.3"
+ "workbox-core": "6.5.4"
}
},
"node_modules/worker-loader": {
@@ -12761,21 +12955,21 @@
"dev": true
},
"@babel/core": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
- "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+ "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
"dev": true,
"requires": {
"@ampproject/remapping": "^2.1.0",
"@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.18.9",
+ "@babel/generator": "^7.18.10",
"@babel/helper-compilation-targets": "^7.18.9",
"@babel/helper-module-transforms": "^7.18.9",
"@babel/helpers": "^7.18.9",
- "@babel/parser": "^7.18.9",
- "@babel/template": "^7.18.6",
- "@babel/traverse": "^7.18.9",
- "@babel/types": "^7.18.9",
+ "@babel/parser": "^7.18.10",
+ "@babel/template": "^7.18.10",
+ "@babel/traverse": "^7.18.10",
+ "@babel/types": "^7.18.10",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@@ -12792,12 +12986,12 @@
}
},
"@babel/generator": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
- "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.10.tgz",
+ "integrity": "sha512-0+sW7e3HjQbiHbj1NeU/vN8ornohYlacAfZIaXhdoGweQqgcNy69COVciYYqEXJ/v+9OBA7Frxm4CVAuNqKeNA==",
"dev": true,
"requires": {
- "@babel/types": "^7.18.9",
+ "@babel/types": "^7.18.10",
"@jridgewell/gen-mapping": "^0.3.2",
"jsesc": "^2.5.1"
},
@@ -12909,6 +13103,12 @@
"@babel/types": "^7.18.6"
}
},
+ "@babel/helper-string-parser": {
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+ "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+ "dev": true
+ },
"@babel/helper-validator-identifier": {
"version": "7.18.6",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -13002,9 +13202,9 @@
}
},
"@babel/parser": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
- "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.10.tgz",
+ "integrity": "sha512-TYk3OA0HKL6qNryUayb5UUEhM/rkOQozIBEA5ITXh5DWrSp0TlUQXMyZmnWxG/DizSWBeeQ0Zbc5z8UGaaqoeg==",
"dev": true
},
"@babel/plugin-syntax-async-generators": {
@@ -13133,30 +13333,30 @@
}
},
"@babel/template": {
- "version": "7.18.6",
- "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
- "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+ "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
- "@babel/parser": "^7.18.6",
- "@babel/types": "^7.18.6"
+ "@babel/parser": "^7.18.10",
+ "@babel/types": "^7.18.10"
}
},
"@babel/traverse": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
- "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.10.tgz",
+ "integrity": "sha512-J7ycxg0/K9XCtLyHf0cz2DqDihonJeIo+z+HEdRe9YuT8TY4A66i+Ab2/xZCEW7Ro60bPCBBfqqboHSamoV3+g==",
"dev": true,
"requires": {
"@babel/code-frame": "^7.18.6",
- "@babel/generator": "^7.18.9",
+ "@babel/generator": "^7.18.10",
"@babel/helper-environment-visitor": "^7.18.9",
"@babel/helper-function-name": "^7.18.9",
"@babel/helper-hoist-variables": "^7.18.6",
"@babel/helper-split-export-declaration": "^7.18.6",
- "@babel/parser": "^7.18.9",
- "@babel/types": "^7.18.9",
+ "@babel/parser": "^7.18.10",
+ "@babel/types": "^7.18.10",
"debug": "^4.1.0",
"globals": "^11.1.0"
},
@@ -13170,11 +13370,12 @@
}
},
"@babel/types": {
- "version": "7.18.9",
- "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
- "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+ "version": "7.18.10",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+ "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
"dev": true,
"requires": {
+ "@babel/helper-string-parser": "^7.18.10",
"@babel/helper-validator-identifier": "^7.18.6",
"to-fast-properties": "^2.0.0"
}
@@ -13208,6 +13409,12 @@
"resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz",
"integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw=="
},
+ "@esbuild/linux-loong64": {
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.14.53.tgz",
+ "integrity": "sha512-W2dAL6Bnyn4xa/QRSU3ilIK4EzD5wgYXKXJiS1HDF5vU3675qc2bvFyLwbUcdmssDveyndy7FbitrCoiV/eMLg==",
+ "optional": true
+ },
"@eslint/eslintrc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.0.tgz",
@@ -13260,9 +13467,9 @@
}
},
"@humanwhocodes/config-array": {
- "version": "0.9.5",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.5.tgz",
- "integrity": "sha512-ObyMyWxZiCu/yTisA7uzx81s40xR2fD5Cg/2Kq7G02ajkNubJf6BopgDTmDyc3U7sXpNKM8cYOw7s7Tyr+DnCw==",
+ "version": "0.10.4",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+ "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
"dev": true,
"requires": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -13270,6 +13477,12 @@
"minimatch": "^3.0.4"
}
},
+ "@humanwhocodes/gitignore-to-minimatch": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+ "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+ "dev": true
+ },
"@humanwhocodes/object-schema": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -13345,12 +13558,6 @@
"p-limit": "^2.2.0"
}
},
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -13987,6 +14194,19 @@
"dev": true,
"requires": {}
},
+ "@mcaptcha/core-glue": {
+ "version": "0.1.0-alpha-3",
+ "resolved": "https://registry.npmjs.org/@mcaptcha/core-glue/-/core-glue-0.1.0-alpha-3.tgz",
+ "integrity": "sha512-avphBVgf3PPDWuUoDsB2qiXAss2pc00lUILswJaMQofr8FQyflzkhha8H2Z+qGFiX0Iib/yyP2TOtBDbHqE9Tg=="
+ },
+ "@mcaptcha/vanilla-glue": {
+ "version": "0.1.0-alpha-2",
+ "resolved": "https://registry.npmjs.org/@mcaptcha/vanilla-glue/-/vanilla-glue-0.1.0-alpha-2.tgz",
+ "integrity": "sha512-cQOg3EIhdjk1xoZtjD9SVPwQAnd49FCvHKchwFZZuhdNTeFs7SUHynOCekuGow2Ip0RJZuMZGcRxvWMgd0ogng==",
+ "requires": {
+ "@mcaptcha/core-glue": "^0.1.0-alpha-3"
+ }
+ },
"@nodelib/fs.scandir": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
@@ -14016,9 +14236,9 @@
"integrity": "sha512-9X2obfABZuDVLCgPK9aX0a/x4jaOEweTTWE2+9sr0Qqqevj2Uv5XorvusThmc9XGYpS9yI+fhh8RTafBtGposw=="
},
"@primer/octicons": {
- "version": "17.3.0",
- "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.3.0.tgz",
- "integrity": "sha512-4zPwwloYWdR6RznMafV7Fsw3n2CeDPp/+qEIQbaX/tBbPY1KmU0OAXmhRfhD5AzgB5kdV1aQ7KnQr1GeQXl9Dg==",
+ "version": "17.4.0",
+ "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz",
+ "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==",
"requires": {
"object-assign": "^4.1.1"
}
@@ -14058,9 +14278,9 @@
}
},
"@sinclair/typebox": {
- "version": "0.24.20",
- "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.20.tgz",
- "integrity": "sha512-kVaO5aEFZb33nPMTZBxiPEkY+slxiPtqC7QX8f9B3eGOMBvEfuMfxp9DSTTCsRJPumPKjrge4yagyssO4q6qzQ==",
+ "version": "0.24.26",
+ "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.26.tgz",
+ "integrity": "sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==",
"dev": true
},
"@sinonjs/commons": {
@@ -14163,9 +14383,9 @@
"dev": true
},
"@stoplight/spectral-cli": {
- "version": "6.4.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.4.1.tgz",
- "integrity": "sha512-l5nWXy/6YEyk51VVrOurhupVScIqfK0ra8yIRSli+gnW5Kf5Nfw5PLci5GceQGaM5WE+wmqZ/iY95yOVFwHc+A==",
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-cli/-/spectral-cli-6.5.0.tgz",
+ "integrity": "sha512-BmTnQkkhG6E301ADUX7dhQtIIUT/WVRszRHy+90M5Bxk+4kod/6Gi8w7sWuQ5myDls3mLEMjYWUOKaUALuPvug==",
"dev": true,
"requires": {
"@rollup/plugin-commonjs": "^20.0.0",
@@ -14218,9 +14438,9 @@
}
},
"@stoplight/spectral-core": {
- "version": "1.12.3",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.12.3.tgz",
- "integrity": "sha512-+PhVzTD8q6kUZw4BcbM+ibVaH5/ELryKt5tlLitA8SJIaJ+5/9ZKaGN0AV3ExZQZGYvXwucPOQuJKYZYKA6mWg==",
+ "version": "1.13.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-core/-/spectral-core-1.13.0.tgz",
+ "integrity": "sha512-h++UIhdYK6bCZYHCK8byeyOq2tgAUbXdwdR3+Wy1O3PrJERdA9fyL0I3KQ595HylZRo7z1PUoSeyY6FMypWTBQ==",
"dev": true,
"requires": {
"@stoplight/better-ajv-errors": "1.0.1",
@@ -14231,11 +14451,13 @@
"@stoplight/spectral-ref-resolver": "^1.0.0",
"@stoplight/spectral-runtime": "^1.0.0",
"@stoplight/types": "~13.2.0",
+ "@types/es-aggregate-error": "^1.0.2",
"@types/json-schema": "^7.0.11",
"ajv": "^8.6.0",
"ajv-errors": "~3.0.0",
"ajv-formats": "~2.1.0",
"blueimp-md5": "2.18.0",
+ "es-aggregate-error": "^1.0.7",
"jsonpath-plus": "6.0.1",
"lodash": "~4.17.21",
"lodash.topath": "^4.5.2",
@@ -14284,9 +14506,9 @@
}
},
"@stoplight/spectral-functions": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.6.1.tgz",
- "integrity": "sha512-f4cFtbI35bQtY0t4fYhKtS+/nMU3UsAeFlqm4tARGGG5WjOv4ieCFNFbgodKNiO3F4O+syMEjVQuXlBNPuY7jw==",
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-functions/-/spectral-functions-1.7.0.tgz",
+ "integrity": "sha512-ya3ovvH17QqHeL1o41rEXISJIUegb763Y8yWI01VaLj4zehKOjLzVNKIp1PsUNkG88M5fwB8Lrvjzcd3M8O3iw==",
"dev": true,
"requires": {
"@stoplight/better-ajv-errors": "1.0.1",
@@ -14344,12 +14566,12 @@
}
},
"@stoplight/spectral-ruleset-bundler": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.0.tgz",
- "integrity": "sha512-6Tif7GQL18F0LN1+FhEmhFWgE/TiWudb/pFl4DC7oS1QRoutB7QJPqIfVFSmteToPidxlrIbC6VAXSyEhlpDVQ==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-ruleset-bundler/-/spectral-ruleset-bundler-1.3.1.tgz",
+ "integrity": "sha512-TWjLFYBor1s/0v3xXwdVzzyUVu7ez2vYVNN4RMbJG7HIZgYW8MMVx4AVg5Eo1ZgLTkj/aeaoAOjIP7t+u6IBUg==",
"dev": true,
"requires": {
- "@rollup/plugin-commonjs": "^21.0.1",
+ "@rollup/plugin-commonjs": "~22.0.0",
"@stoplight/path": "1.3.2",
"@stoplight/spectral-core": ">=1",
"@stoplight/spectral-formats": ">=1",
@@ -14362,15 +14584,15 @@
"@stoplight/types": "^12.3.0",
"@types/node": "*",
"pony-cause": "1.1.1",
- "rollup": "~2.67.0",
+ "rollup": "~2.75.5",
"tslib": "^2.3.1",
"validate-npm-package-name": "3.0.0"
},
"dependencies": {
"@rollup/plugin-commonjs": {
- "version": "21.1.0",
- "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-21.1.0.tgz",
- "integrity": "sha512-6ZtHx3VHIp2ReNNDxHjuUml6ur+WcQ28N1yHgCQwsbNkQg2suhxGMDQGJOn/KuDxKtd1xuZP5xSTwBA4GQ8hbA==",
+ "version": "22.0.1",
+ "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-22.0.1.tgz",
+ "integrity": "sha512-dGfEZvdjDHObBiP5IvwTKMVeq/tBZGMBHZFMdIV1ClMM/YoWS34xrHFGfag9SN2ZtMgNZRFruqvxZQEa70O6nQ==",
"dev": true,
"requires": {
"@rollup/pluginutils": "^3.1.0",
@@ -14383,9 +14605,9 @@
}
},
"rollup": {
- "version": "2.67.3",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.67.3.tgz",
- "integrity": "sha512-G/x1vUwbGtP6O5ZM8/sWr8+p7YfZhI18pPqMRtMYMWSbHjKZ/ajHGiM+GWNTlWyOR0EHIdT8LHU+Z4ciIZ1oBw==",
+ "version": "2.75.7",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.75.7.tgz",
+ "integrity": "sha512-VSE1iy0eaAYNCxEXaleThdFXqZJ42qDBatAwrfnPlENEZ8erQ+0LYX4JXOLPceWfZpV1VtZwZ3dFCuOZiSyFtQ==",
"dev": true,
"requires": {
"fsevents": "~2.3.2"
@@ -14424,9 +14646,9 @@
}
},
"@stoplight/spectral-rulesets": {
- "version": "1.11.0",
- "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.0.tgz",
- "integrity": "sha512-0zFbxIuoWmGrkl2txOuaEDF8o6aoKDpMAYOG2oDfmmX9FhXX3c3ivIy80hyb2tMKkIYuqqx/zwIiOuww5S8iUA==",
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/@stoplight/spectral-rulesets/-/spectral-rulesets-1.11.1.tgz",
+ "integrity": "sha512-0MDr5MW000FIZ3C47YY2Cg4NzU6wJFvvpSl1QRijRzdAVqQ1DgD3FgRDKHTA6OO7BmgWdCQYKSI8KwOH1Ju3kw==",
"dev": true,
"requires": {
"@asyncapi/specs": "^2.14.0",
@@ -14575,6 +14797,15 @@
"@types/node": "*"
}
},
+ "@types/es-aggregate-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@types/es-aggregate-error/-/es-aggregate-error-1.0.2.tgz",
+ "integrity": "sha512-erqUpFXksaeR2kejKnhnjZjbFxUpGZx4Z7ydNL9ie8tEhXPiZTsLeUDJ6aR1F8j5wWUAtOAQWUqkc7givBJbBA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*"
+ }
+ },
"@types/eslint": {
"version": "8.4.5",
"resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.5.tgz",
@@ -14663,9 +14894,9 @@
"dev": true
},
"@types/node": {
- "version": "18.0.6",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-18.0.6.tgz",
- "integrity": "sha512-/xUq6H2aQm261exT6iZTMifUySEt4GR5KX8eYyY+C4MSNPqSh9oNIP7tz2GLKTlFaiBbgZNxffoR3CVRG+cljw=="
+ "version": "18.6.3",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
+ "integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg=="
},
"@types/normalize-package-data": {
"version": "2.4.1",
@@ -14680,9 +14911,9 @@
"dev": true
},
"@types/prettier": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz",
- "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==",
+ "version": "2.6.4",
+ "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.4.tgz",
+ "integrity": "sha512-fOwvpvQYStpb/zHMx0Cauwywu9yLDmzWiiQBC7gJyq5tYLUXFZvDG7VK1B7WBxxjBJNKFOZ0zLoOQn8vmATbhw==",
"dev": true
},
"@types/qs": {
@@ -14943,9 +15174,9 @@
}
},
"acorn": {
- "version": "8.7.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
- "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A=="
+ "version": "8.8.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+ "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w=="
},
"acorn-import-assertions": {
"version": "1.8.0",
@@ -15267,14 +15498,14 @@
}
},
"browserslist": {
- "version": "4.21.2",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.2.tgz",
- "integrity": "sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA==",
+ "version": "4.21.3",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+ "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
"requires": {
- "caniuse-lite": "^1.0.30001366",
- "electron-to-chromium": "^1.4.188",
+ "caniuse-lite": "^1.0.30001370",
+ "electron-to-chromium": "^1.4.202",
"node-releases": "^2.0.6",
- "update-browserslist-db": "^1.0.4"
+ "update-browserslist-db": "^1.0.5"
}
},
"bser": {
@@ -15343,9 +15574,9 @@
}
},
"caniuse-lite": {
- "version": "1.0.30001367",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001367.tgz",
- "integrity": "sha512-XDgbeOHfifWV3GEES2B8rtsrADx4Jf+juKX2SICJcaUhjYBO3bR96kvEIHa15VU6ohtOhBZuPGGYGbXMRn0NCw=="
+ "version": "1.0.30001373",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001373.tgz",
+ "integrity": "sha512-pJYArGHrPp3TUqQzFYRmP/lwJlj8RCbVe3Gd3eJQkAV8SAC6b19XS9BjMvRdvaS8RMkaTN8ZhoHP6S1y8zzwEQ=="
},
"caseless": {
"version": "0.12.0",
@@ -15463,9 +15694,9 @@
"dev": true
},
"codemirror": {
- "version": "5.65.6",
- "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.6.tgz",
- "integrity": "sha512-zNihMSMoDxK9Gqv9oEyDT8oM51rcRrQ+IEo2zyS48gJByBq5Fj8XuNEguMra+MuIOuh6lkpnLUJeL70DoTt6yw=="
+ "version": "5.65.7",
+ "resolved": "https://registry.npmjs.org/codemirror/-/codemirror-5.65.7.tgz",
+ "integrity": "sha512-zb67cXzgugIQmb6tfD4G11ILjYoMfTjwcjn+cWsa4GewlI2adhR/h3kolkoCQTm1msD/1BuqVTKuO09ELsS++A=="
},
"codemirror-spell-checker": {
"version": "1.1.2",
@@ -15515,9 +15746,10 @@
}
},
"commander": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
- "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
+ "version": "9.4.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
+ "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
+ "dev": true
},
"commondir": {
"version": "1.0.1",
@@ -15816,6 +16048,13 @@
"commander": "7",
"iconv-lite": "0.6",
"rw": "1"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
+ }
}
},
"d3-ease": {
@@ -16426,6 +16665,14 @@
"domelementtype": "^2.0.1",
"domhandler": "^4.2.0",
"entities": "^2.0.0"
+ },
+ "dependencies": {
+ "entities": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
+ "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "dev": true
+ }
}
},
"domelementtype": {
@@ -16486,9 +16733,9 @@
}
},
"electron-to-chromium": {
- "version": "1.4.195",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.195.tgz",
- "integrity": "sha512-vefjEh0sk871xNmR5whJf9TEngX+KTKS3hOHpjoMpauKkwlGwtMz1H8IaIjAT/GNnX0TbGwAdmVoXCAzXf+PPg=="
+ "version": "1.4.210",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.210.tgz",
+ "integrity": "sha512-kSiX4tuyZijV7Cz0MWVmGT8K2siqaOA4Z66K5dCttPPRh0HicOcOAEj1KlC8O8J1aOS/1M8rGofOzksLKaHWcQ=="
},
"emittery": {
"version": "0.10.2",
@@ -16516,9 +16763,9 @@
}
},
"entities": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz",
- "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==",
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
+ "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
"dev": true
},
"envinfo": {
@@ -16581,6 +16828,21 @@
"unbox-primitive": "^1.0.2"
}
},
+ "es-aggregate-error": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/es-aggregate-error/-/es-aggregate-error-1.0.8.tgz",
+ "integrity": "sha512-AKUb5MKLWMozPlFRHOKqWD7yta5uaEhH21qwtnf6FlKjNjTJOoqFi0/G14+FfSkIQhhu6X68Af4xgRC6y8qG4A==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.19.5",
+ "function-bind": "^1.1.1",
+ "functions-have-names": "^1.2.3",
+ "get-intrinsic": "^1.1.1",
+ "globalthis": "^1.0.2",
+ "has-property-descriptors": "^1.0.0"
+ }
+ },
"es-module-lexer": {
"version": "0.9.3",
"resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz",
@@ -16607,114 +16869,115 @@
}
},
"esbuild": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.49.tgz",
- "integrity": "sha512-/TlVHhOaq7Yz8N1OJrjqM3Auzo5wjvHFLk+T8pIue+fhnhIMpfAzsG6PLVMbFveVxqD2WOp3QHei+52IMUNmCw==",
- "requires": {
- "esbuild-android-64": "0.14.49",
- "esbuild-android-arm64": "0.14.49",
- "esbuild-darwin-64": "0.14.49",
- "esbuild-darwin-arm64": "0.14.49",
- "esbuild-freebsd-64": "0.14.49",
- "esbuild-freebsd-arm64": "0.14.49",
- "esbuild-linux-32": "0.14.49",
- "esbuild-linux-64": "0.14.49",
- "esbuild-linux-arm": "0.14.49",
- "esbuild-linux-arm64": "0.14.49",
- "esbuild-linux-mips64le": "0.14.49",
- "esbuild-linux-ppc64le": "0.14.49",
- "esbuild-linux-riscv64": "0.14.49",
- "esbuild-linux-s390x": "0.14.49",
- "esbuild-netbsd-64": "0.14.49",
- "esbuild-openbsd-64": "0.14.49",
- "esbuild-sunos-64": "0.14.49",
- "esbuild-windows-32": "0.14.49",
- "esbuild-windows-64": "0.14.49",
- "esbuild-windows-arm64": "0.14.49"
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.14.53.tgz",
+ "integrity": "sha512-ohO33pUBQ64q6mmheX1mZ8mIXj8ivQY/L4oVuAshr+aJI+zLl+amrp3EodrUNDNYVrKJXGPfIHFGhO8slGRjuw==",
+ "requires": {
+ "@esbuild/linux-loong64": "0.14.53",
+ "esbuild-android-64": "0.14.53",
+ "esbuild-android-arm64": "0.14.53",
+ "esbuild-darwin-64": "0.14.53",
+ "esbuild-darwin-arm64": "0.14.53",
+ "esbuild-freebsd-64": "0.14.53",
+ "esbuild-freebsd-arm64": "0.14.53",
+ "esbuild-linux-32": "0.14.53",
+ "esbuild-linux-64": "0.14.53",
+ "esbuild-linux-arm": "0.14.53",
+ "esbuild-linux-arm64": "0.14.53",
+ "esbuild-linux-mips64le": "0.14.53",
+ "esbuild-linux-ppc64le": "0.14.53",
+ "esbuild-linux-riscv64": "0.14.53",
+ "esbuild-linux-s390x": "0.14.53",
+ "esbuild-netbsd-64": "0.14.53",
+ "esbuild-openbsd-64": "0.14.53",
+ "esbuild-sunos-64": "0.14.53",
+ "esbuild-windows-32": "0.14.53",
+ "esbuild-windows-64": "0.14.53",
+ "esbuild-windows-arm64": "0.14.53"
}
},
"esbuild-android-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.49.tgz",
- "integrity": "sha512-vYsdOTD+yi+kquhBiFWl3tyxnj2qZJsl4tAqwhT90ktUdnyTizgle7TjNx6Ar1bN7wcwWqZ9QInfdk2WVagSww==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-android-64/-/esbuild-android-64-0.14.53.tgz",
+ "integrity": "sha512-fIL93sOTnEU+NrTAVMIKiAw0YH22HWCAgg4N4Z6zov2t0kY9RAJ50zY9ZMCQ+RT6bnOfDt8gCTnt/RaSNA2yRA==",
"optional": true
},
"esbuild-android-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.49.tgz",
- "integrity": "sha512-g2HGr/hjOXCgSsvQZ1nK4nW/ei8JUx04Li74qub9qWrStlysaVmadRyTVuW32FGIpLQyc5sUjjZopj49eGGM2g==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-android-arm64/-/esbuild-android-arm64-0.14.53.tgz",
+ "integrity": "sha512-PC7KaF1v0h/nWpvlU1UMN7dzB54cBH8qSsm7S9mkwFA1BXpaEOufCg8hdoEI1jep0KeO/rjZVWrsH8+q28T77A==",
"optional": true
},
"esbuild-darwin-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.49.tgz",
- "integrity": "sha512-3rvqnBCtX9ywso5fCHixt2GBCUsogNp9DjGmvbBohh31Ces34BVzFltMSxJpacNki96+WIcX5s/vum+ckXiLYg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-64/-/esbuild-darwin-64-0.14.53.tgz",
+ "integrity": "sha512-gE7P5wlnkX4d4PKvLBUgmhZXvL7lzGRLri17/+CmmCzfncIgq8lOBvxGMiQ4xazplhxq+72TEohyFMZLFxuWvg==",
"optional": true
},
"esbuild-darwin-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.49.tgz",
- "integrity": "sha512-XMaqDxO846srnGlUSJnwbijV29MTKUATmOLyQSfswbK/2X5Uv28M9tTLUJcKKxzoo9lnkYPsx2o8EJcTYwCs/A==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.53.tgz",
+ "integrity": "sha512-otJwDU3hnI15Q98PX4MJbknSZ/WSR1I45il7gcxcECXzfN4Mrpft5hBDHXNRnCh+5858uPXBXA1Vaz2jVWLaIA==",
"optional": true
},
"esbuild-freebsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.49.tgz",
- "integrity": "sha512-NJ5Q6AjV879mOHFri+5lZLTp5XsO2hQ+KSJYLbfY9DgCu8s6/Zl2prWXVANYTeCDLlrIlNNYw8y34xqyLDKOmQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.53.tgz",
+ "integrity": "sha512-WkdJa8iyrGHyKiPF4lk0MiOF87Q2SkE+i+8D4Cazq3/iqmGPJ6u49je300MFi5I2eUsQCkaOWhpCVQMTKGww2w==",
"optional": true
},
"esbuild-freebsd-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.49.tgz",
- "integrity": "sha512-lFLtgXnAc3eXYqj5koPlBZvEbBSOSUbWO3gyY/0+4lBdRqELyz4bAuamHvmvHW5swJYL7kngzIZw6kdu25KGOA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.53.tgz",
+ "integrity": "sha512-9T7WwCuV30NAx0SyQpw8edbKvbKELnnm1FHg7gbSYaatH+c8WJW10g/OdM7JYnv7qkimw2ZTtSA+NokOLd2ydQ==",
"optional": true
},
"esbuild-linux-32": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.49.tgz",
- "integrity": "sha512-zTTH4gr2Kb8u4QcOpTDVn7Z8q7QEIvFl/+vHrI3cF6XOJS7iEI1FWslTo3uofB2+mn6sIJEQD9PrNZKoAAMDiA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-32/-/esbuild-linux-32-0.14.53.tgz",
+ "integrity": "sha512-VGanLBg5en2LfGDgLEUxQko2lqsOS7MTEWUi8x91YmsHNyzJVT/WApbFFx3MQGhkf+XdimVhpyo5/G0PBY91zg==",
"optional": true
},
"esbuild-linux-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.49.tgz",
- "integrity": "sha512-hYmzRIDzFfLrB5c1SknkxzM8LdEUOusp6M2TnuQZJLRtxTgyPnZZVtyMeCLki0wKgYPXkFsAVhi8vzo2mBNeTg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-64/-/esbuild-linux-64-0.14.53.tgz",
+ "integrity": "sha512-pP/FA55j/fzAV7N9DF31meAyjOH6Bjuo3aSKPh26+RW85ZEtbJv9nhoxmGTd9FOqjx59Tc1ZbrJabuiXlMwuZQ==",
"optional": true
},
"esbuild-linux-arm": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.49.tgz",
- "integrity": "sha512-iE3e+ZVv1Qz1Sy0gifIsarJMQ89Rpm9mtLSRtG3AH0FPgAzQ5Z5oU6vYzhc/3gSPi2UxdCOfRhw2onXuFw/0lg==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm/-/esbuild-linux-arm-0.14.53.tgz",
+ "integrity": "sha512-/u81NGAVZMopbmzd21Nu/wvnKQK3pT4CrvQ8BTje1STXcQAGnfyKgQlj3m0j2BzYbvQxSy+TMck4TNV2onvoPA==",
"optional": true
},
"esbuild-linux-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.49.tgz",
- "integrity": "sha512-KLQ+WpeuY+7bxukxLz5VgkAAVQxUv67Ft4DmHIPIW+2w3ObBPQhqNoeQUHxopoW/aiOn3m99NSmSV+bs4BSsdA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.53.tgz",
+ "integrity": "sha512-GDmWITT+PMsjCA6/lByYk7NyFssW4Q6in32iPkpjZ/ytSyH+xeEx8q7HG3AhWH6heemEYEWpTll/eui3jwlSnw==",
"optional": true
},
"esbuild-linux-mips64le": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.49.tgz",
- "integrity": "sha512-n+rGODfm8RSum5pFIqFQVQpYBw+AztL8s6o9kfx7tjfK0yIGF6tm5HlG6aRjodiiKkH2xAiIM+U4xtQVZYU4rA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.53.tgz",
+ "integrity": "sha512-d6/XHIQW714gSSp6tOOX2UscedVobELvQlPMkInhx1NPz4ThZI9uNLQ4qQJHGBGKGfu+rtJsxM4NVHLhnNRdWQ==",
"optional": true
},
"esbuild-linux-ppc64le": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.49.tgz",
- "integrity": "sha512-WP9zR4HX6iCBmMFH+XHHng2LmdoIeUmBpL4aL2TR8ruzXyT4dWrJ5BSbT8iNo6THN8lod6GOmYDLq/dgZLalGw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.53.tgz",
+ "integrity": "sha512-ndnJmniKPCB52m+r6BtHHLAOXw+xBCWIxNnedbIpuREOcbSU/AlyM/2dA3BmUQhsHdb4w3amD5U2s91TJ3MzzA==",
"optional": true
},
"esbuild-linux-riscv64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.49.tgz",
- "integrity": "sha512-h66ORBz+Dg+1KgLvzTVQEA1LX4XBd1SK0Fgbhhw4akpG/YkN8pS6OzYI/7SGENiN6ao5hETRDSkVcvU9NRtkMQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.53.tgz",
+ "integrity": "sha512-yG2sVH+QSix6ct4lIzJj329iJF3MhloLE6/vKMQAAd26UVPVkhMFqFopY+9kCgYsdeWvXdPgmyOuKa48Y7+/EQ==",
"optional": true
},
"esbuild-linux-s390x": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.49.tgz",
- "integrity": "sha512-DhrUoFVWD+XmKO1y7e4kNCqQHPs6twz6VV6Uezl/XHYGzM60rBewBF5jlZjG0nCk5W/Xy6y1xWeopkrhFFM0sQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.53.tgz",
+ "integrity": "sha512-OCJlgdkB+XPYndHmw6uZT7jcYgzmx9K+28PVdOa/eLjdoYkeAFvH5hTwX4AXGLZLH09tpl4bVsEtvuyUldaNCg==",
"optional": true
},
"esbuild-loader": {
@@ -16731,39 +16994,39 @@
}
},
"esbuild-netbsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.49.tgz",
- "integrity": "sha512-BXaUwFOfCy2T+hABtiPUIpWjAeWK9P8O41gR4Pg73hpzoygVGnj0nI3YK4SJhe52ELgtdgWP/ckIkbn2XaTxjQ==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.53.tgz",
+ "integrity": "sha512-gp2SB+Efc7MhMdWV2+pmIs/Ja/Mi5rjw+wlDmmbIn68VGXBleNgiEZG+eV2SRS0kJEUyHNedDtwRIMzaohWedQ==",
"optional": true
},
"esbuild-openbsd-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.49.tgz",
- "integrity": "sha512-lP06UQeLDGmVPw9Rg437Btu6J9/BmyhdoefnQ4gDEJTtJvKtQaUcOQrhjTq455ouZN4EHFH1h28WOJVANK41kA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.53.tgz",
+ "integrity": "sha512-eKQ30ZWe+WTZmteDYg8S+YjHV5s4iTxeSGhJKJajFfQx9TLZJvsJX0/paqwP51GicOUruFpSUAs2NCc0a4ivQQ==",
"optional": true
},
"esbuild-sunos-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.49.tgz",
- "integrity": "sha512-4c8Zowp+V3zIWje329BeLbGh6XI9c/rqARNaj5yPHdC61pHI9UNdDxT3rePPJeWcEZVKjkiAS6AP6kiITp7FSw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-sunos-64/-/esbuild-sunos-64-0.14.53.tgz",
+ "integrity": "sha512-OWLpS7a2FrIRukQqcgQqR1XKn0jSJoOdT+RlhAxUoEQM/IpytS3FXzCJM6xjUYtpO5GMY0EdZJp+ur2pYdm39g==",
"optional": true
},
"esbuild-windows-32": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.49.tgz",
- "integrity": "sha512-q7Rb+J9yHTeKr9QTPDYkqfkEj8/kcKz9lOabDuvEXpXuIcosWCJgo5Z7h/L4r7rbtTH4a8U2FGKb6s1eeOHmJA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-32/-/esbuild-windows-32-0.14.53.tgz",
+ "integrity": "sha512-m14XyWQP5rwGW0tbEfp95U6A0wY0DYPInWBB7D69FAXUpBpBObRoGTKRv36lf2RWOdE4YO3TNvj37zhXjVL5xg==",
"optional": true
},
"esbuild-windows-64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.49.tgz",
- "integrity": "sha512-+Cme7Ongv0UIUTniPqfTX6mJ8Deo7VXw9xN0yJEN1lQMHDppTNmKwAM3oGbD/Vqff+07K2gN0WfNkMohmG+dVw==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-64/-/esbuild-windows-64-0.14.53.tgz",
+ "integrity": "sha512-s9skQFF0I7zqnQ2K8S1xdLSfZFsPLuOGmSx57h2btSEswv0N0YodYvqLcJMrNMXh6EynOmWD7rz+0rWWbFpIHQ==",
"optional": true
},
"esbuild-windows-arm64": {
- "version": "0.14.49",
- "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.49.tgz",
- "integrity": "sha512-v+HYNAXzuANrCbbLFJ5nmO3m5y2PGZWLe3uloAkLt87aXiO2mZr3BTmacZdjwNkNEHuH3bNtN8cak+mzVjVPfA==",
+ "version": "0.14.53",
+ "resolved": "https://registry.npmjs.org/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.53.tgz",
+ "integrity": "sha512-E+5Gvb+ZWts+00T9II6wp2L3KG2r3iGxByqd/a1RmLmYWVsSVUjkvIxZuJ3hYTIbhLkH5PRwpldGTKYqVz0nzQ==",
"optional": true
},
"escalade": {
@@ -16843,13 +17106,14 @@
}
},
"eslint": {
- "version": "8.20.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
- "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+ "version": "8.21.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+ "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
"dev": true,
"requires": {
"@eslint/eslintrc": "^1.3.0",
- "@humanwhocodes/config-array": "^0.9.2",
+ "@humanwhocodes/config-array": "^0.10.4",
+ "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
"ajv": "^6.10.0",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
@@ -16859,14 +17123,17 @@
"eslint-scope": "^7.1.1",
"eslint-utils": "^3.0.0",
"eslint-visitor-keys": "^3.3.0",
- "espree": "^9.3.2",
+ "espree": "^9.3.3",
"esquery": "^1.4.0",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
"file-entry-cache": "^6.0.1",
+ "find-up": "^5.0.0",
"functional-red-black-tree": "^1.0.1",
"glob-parent": "^6.0.1",
"globals": "^13.15.0",
+ "globby": "^11.1.0",
+ "grapheme-splitter": "^1.0.4",
"ignore": "^5.2.0",
"import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
@@ -16944,6 +17211,55 @@
"requires": {
"ms": "^2.1.1"
}
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
+ "dev": true
}
}
},
@@ -17002,9 +17318,9 @@
"requires": {}
},
"eslint-plugin-sonarjs": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.13.0.tgz",
- "integrity": "sha512-t3m7ta0EspzDxSOZh3cEOJIJVZgN/TlJYaBGnQlK6W/PZNbWep8q4RQskkJkA7/zwNpX0BaoEOSUUrqaADVoqA==",
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-sonarjs/-/eslint-plugin-sonarjs-0.14.0.tgz",
+ "integrity": "sha512-0X0q3fB8ghppms19cR2oIK2ajoFp7DEy3AVGDqO7WX02r1aWOzkrHa+veatGZw+R7amgBvfcF0qHCG66p9Zoag==",
"dev": true,
"requires": {}
},
@@ -17031,9 +17347,9 @@
}
},
"eslint-plugin-vue": {
- "version": "9.2.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.2.0.tgz",
- "integrity": "sha512-W2hc+NUXoce8sZtWgZ45miQTy6jNyuSdub5aZ1IBune4JDeAyzucYX0TzkrQ1jMO52sNUDYlCIHDoaNePe0p5g==",
+ "version": "9.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-vue/-/eslint-plugin-vue-9.3.0.tgz",
+ "integrity": "sha512-iscKKkBZgm6fGZwFt6poRoWC0Wy2dQOlwUPW++CiPoQiw1enctV2Hj5DBzzjJZfyqs+FAXhgzL4q0Ww03AgSmQ==",
"dev": true,
"requires": {
"eslint-utils": "^3.0.0",
@@ -17079,12 +17395,12 @@
"dev": true
},
"espree": {
- "version": "9.3.2",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
- "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+ "version": "9.3.3",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+ "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
"dev": true,
"requires": {
- "acorn": "^8.7.1",
+ "acorn": "^8.8.0",
"acorn-jsx": "^5.3.2",
"eslint-visitor-keys": "^3.3.0"
}
@@ -17286,9 +17602,9 @@
"dev": true
},
"fastest-levenshtein": {
- "version": "1.0.14",
- "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.14.tgz",
- "integrity": "sha512-tFfWHjnuUfKE186Tfgr+jtaFc0mZTApEgKDOeyN+FwOqRkO/zK/3h1AiRd8u8CY53owL3CUmGr/oI9p/RdyLTA=="
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+ "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg=="
},
"fastq": {
"version": "1.13.0",
@@ -17331,12 +17647,13 @@
}
},
"find-up": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
- "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
"dev": true,
"requires": {
- "locate-path": "^2.0.0"
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
}
},
"flat-cache": {
@@ -17487,9 +17804,9 @@
}
},
"get-stdin": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
- "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
+ "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
"dev": true
},
"get-stream": {
@@ -17569,6 +17886,12 @@
"which": "^1.3.1"
},
"dependencies": {
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "dev": true
+ },
"which": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
@@ -17581,14 +17904,23 @@
}
},
"globals": {
- "version": "13.16.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.16.0.tgz",
- "integrity": "sha512-A1lrQfpNF+McdPOnnFqY3kSN0AFTy485bTi1bkLk4mVPODIUEcSfhHgRqA+QdXPksrSTTztYXx37NFV+GpGk3Q==",
+ "version": "13.17.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz",
+ "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==",
"dev": true,
"requires": {
"type-fest": "^0.20.2"
}
},
+ "globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3"
+ }
+ },
"globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -17614,6 +17946,12 @@
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz",
"integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
},
+ "grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
+ },
"graphlib": {
"version": "2.1.8",
"resolved": "https://registry.npmjs.org/graphlib/-/graphlib-2.1.8.tgz",
@@ -17872,9 +18210,9 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
- "version": "1.3.8",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
- "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
+ "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
"dev": true
},
"internal-slot": {
@@ -17930,12 +18268,12 @@
}
},
"is-builtin-module": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.1.0.tgz",
- "integrity": "sha512-OV7JjAgOTfAFJmHZLvpSTb4qi0nIILDV1gWPYDnDJUTNFM5aGlRAhk4QcT8i7TuAleeEV5Fdkqn3t4mS+Q11fg==",
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.0.tgz",
+ "integrity": "sha512-phDA4oSGt7vl1n5tJvTWooWWAsXLY+2xCnxNqvKhGEzujg+A43wPlPOyDg3C8XQHN+6k/JTQWJ/j0dQh/qr+Hw==",
"dev": true,
"requires": {
- "builtin-modules": "^3.0.0"
+ "builtin-modules": "^3.3.0"
}
},
"is-callable": {
@@ -19624,13 +19962,12 @@
}
},
"locate-path": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
- "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==",
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
"dev": true,
"requires": {
- "p-locate": "^2.0.0",
- "path-exists": "^3.0.0"
+ "p-locate": "^5.0.0"
}
},
"lodash": {
@@ -19751,14 +20088,6 @@
"linkify-it": "^4.0.1",
"mdurl": "^1.0.1",
"uc.micro": "^1.0.5"
- },
- "dependencies": {
- "entities": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/entities/-/entities-3.0.1.tgz",
- "integrity": "sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==",
- "dev": true
- }
}
},
"markdownlint": {
@@ -19797,18 +20126,6 @@
"balanced-match": "^1.0.0"
}
},
- "commander": {
- "version": "9.4.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.0.tgz",
- "integrity": "sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw==",
- "dev": true
- },
- "get-stdin": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
- "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
- "dev": true
- },
"glob": {
"version": "8.0.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-8.0.3.tgz",
@@ -20265,29 +20582,12 @@
}
},
"p-locate": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
- "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
"dev": true,
"requires": {
- "p-limit": "^1.1.0"
- },
- "dependencies": {
- "p-limit": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
- "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
- "dev": true,
- "requires": {
- "p-try": "^1.0.0"
- }
- },
- "p-try": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
- "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==",
- "dev": true
- }
+ "p-limit": "^3.0.2"
}
},
"p-try": {
@@ -20361,10 +20661,9 @@
"integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA=="
},
"path-exists": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
- "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==",
- "dev": true
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
},
"path-is-absolute": {
"version": "1.0.1",
@@ -20449,11 +20748,6 @@
"requires": {
"p-limit": "^2.2.0"
}
- },
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="
}
}
},
@@ -20790,12 +21084,6 @@
"p-limit": "^2.2.0"
}
},
- "path-exists": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
- "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
- "dev": true
- },
"type-fest": {
"version": "0.8.1",
"resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz",
@@ -20936,9 +21224,9 @@
"integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
},
"rollup": {
- "version": "2.77.0",
- "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
- "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+ "version": "2.77.2",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.2.tgz",
+ "integrity": "sha512-m/4YzYgLcpMQbxX3NmAqDvwLATZzxt8bIegO78FZLl+lAgKJBd1DRAOeEiZcKOIOPjxE6ewHWHNgGEalFXuz1g==",
"dev": true,
"peer": true,
"requires": {
@@ -20955,14 +21243,6 @@
"ini": "~3.0.0",
"minimist": "^1.2.6",
"strip-json-comments": "~3.1.1"
- },
- "dependencies": {
- "ini": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ini/-/ini-3.0.0.tgz",
- "integrity": "sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw==",
- "dev": true
- }
}
},
"run-parallel": {
@@ -21448,6 +21728,12 @@
"integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==",
"dev": true
},
+ "get-stdin": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
+ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
+ "dev": true
+ },
"resolve-from": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
@@ -21525,12 +21811,20 @@
"csso": "^4.2.0",
"picocolors": "^1.0.0",
"stable": "^0.1.8"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+ "dev": true
+ }
}
},
"swagger-ui-dist": {
- "version": "4.13.0",
- "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.0.tgz",
- "integrity": "sha512-5yqhkUU9uV5oT/MTMBeSgDGI0Vx6eCOU43AszQBs88poI8OB1v+FoXEFHv+NaBbEfTkXCMWlAJrH6iWyDzLETQ=="
+ "version": "4.13.2",
+ "resolved": "https://registry.npmjs.org/swagger-ui-dist/-/swagger-ui-dist-4.13.2.tgz",
+ "integrity": "sha512-jHL6UyIYpvEI7NsuWd0R3hJaPQTg6Oo4qSBo+oVfOEkv6rrQm/475RGSMmZgV6ajp+Sgrp9CqrDjQYAgQqiv1A=="
},
"sync-request": {
"version": "6.1.0",
@@ -21828,9 +22122,9 @@
"dev": true
},
"typo-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.1.tgz",
- "integrity": "sha512-bTGLjbD3WqZDR3CgEFkyi9Q/SS2oM29ipXrWfDb4M74ea69QwKAECVceYpaBu0GfdnASMg9Qfl67ttB23nePHg=="
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/typo-js/-/typo-js-1.2.2.tgz",
+ "integrity": "sha512-C7pYBQK17EjSg8tVNY91KHdUt5Nf6FMJ+c3js076quPmBML57PmNMzAcIq/2kf/hSYtFABNDIYNYlJRl5BJhGw=="
},
"uc.micro": {
"version": "1.0.6",
@@ -21877,9 +22171,9 @@
}
},
"updates": {
- "version": "13.1.2",
- "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.2.tgz",
- "integrity": "sha512-wixXdKufbYwxKFMqWmkjnf6vlkZ8Lpx8fWYFrkxawNO9j7xlGQHCtbqW7LHkl/+tl57fFlvgvQ5dAIrseqk3Qw==",
+ "version": "13.1.4",
+ "resolved": "https://registry.npmjs.org/updates/-/updates-13.1.4.tgz",
+ "integrity": "sha512-s8FKpHpREDoIbd1JDcEvsdf+wenhcQjrZK8v7OTIW69kozPttm6rW84Mm/LFouiDVYgaubY3us7sZlRUiGVx4Q==",
"dev": true
},
"uri-js": {
@@ -22114,20 +22408,20 @@
"dev": true
},
"webpack": {
- "version": "5.73.0",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.73.0.tgz",
- "integrity": "sha512-svjudQRPPa0YiOYa2lM/Gacw0r6PvxptHj4FuEKQ2kX05ZLkjbVc5MnPs6its5j7IZljnIqSVo/OsY2X0IpHGA==",
+ "version": "5.74.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.74.0.tgz",
+ "integrity": "sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA==",
"requires": {
"@types/eslint-scope": "^3.7.3",
"@types/estree": "^0.0.51",
"@webassemblyjs/ast": "1.11.1",
"@webassemblyjs/wasm-edit": "1.11.1",
"@webassemblyjs/wasm-parser": "1.11.1",
- "acorn": "^8.4.1",
+ "acorn": "^8.7.1",
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
- "enhanced-resolve": "^5.9.3",
+ "enhanced-resolve": "^5.10.0",
"es-module-lexer": "^0.9.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
@@ -22140,7 +22434,7 @@
"schema-utils": "^3.1.0",
"tapable": "^2.1.1",
"terser-webpack-plugin": "^5.1.3",
- "watchpack": "^2.3.1",
+ "watchpack": "^2.4.0",
"webpack-sources": "^3.2.3"
},
"dependencies": {
@@ -22219,6 +22513,13 @@
"interpret": "^2.2.0",
"rechoir": "^0.7.0",
"webpack-merge": "^5.7.3"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+ "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw=="
+ }
}
},
"webpack-merge": {
@@ -22311,24 +22612,24 @@
"dev": true
},
"workbox-core": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.3.tgz",
- "integrity": "sha512-Bb9ey5n/M9x+l3fBTlLpHt9ASTzgSGj6vxni7pY72ilB/Pb3XtN+cZ9yueboVhD5+9cNQrC9n/E1fSrqWsUz7Q=="
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-core/-/workbox-core-6.5.4.tgz",
+ "integrity": "sha512-OXYb+m9wZm8GrORlV2vBbE5EC1FKu71GGp0H4rjmxmF4/HLbMCoTFws87M3dFwgpmg0v00K++PImpNQ6J5NQ6Q=="
},
"workbox-routing": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.3.tgz",
- "integrity": "sha512-DFjxcuRAJjjt4T34RbMm3MCn+xnd36UT/2RfPRfa8VWJGItGJIn7tG+GwVTdHmvE54i/QmVTJepyAGWtoLPTmg==",
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-routing/-/workbox-routing-6.5.4.tgz",
+ "integrity": "sha512-apQswLsbrrOsBUWtr9Lf80F+P1sHnQdYodRo32SjiByYi36IDyL2r7BH1lJtFX8fwNHDa1QOVY74WKLLS6o5Pg==",
"requires": {
- "workbox-core": "6.5.3"
+ "workbox-core": "6.5.4"
}
},
"workbox-strategies": {
- "version": "6.5.3",
- "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.3.tgz",
- "integrity": "sha512-MgmGRrDVXs7rtSCcetZgkSZyMpRGw8HqL2aguszOc3nUmzGZsT238z/NN9ZouCxSzDu3PQ3ZSKmovAacaIhu1w==",
+ "version": "6.5.4",
+ "resolved": "https://registry.npmjs.org/workbox-strategies/-/workbox-strategies-6.5.4.tgz",
+ "integrity": "sha512-DEtsxhx0LIYWkJBTQolRxG4EI0setTJkqR4m7r4YpBdxtWJH1Mbg01Cj8ZjNOO8etqfA3IZaOPHUxCs8cBsKLw==",
"requires": {
- "workbox-core": "6.5.3"
+ "workbox-core": "6.5.4"
}
},
"worker-loader": {
diff --git a/package.json b/package.json
index e4741f98fec8..42cba24f8515 100644
--- a/package.json
+++ b/package.json
@@ -8,7 +8,8 @@
},
"dependencies": {
"@claviska/jquery-minicolors": "2.3.6",
- "@primer/octicons": "17.3.0",
+ "@mcaptcha/vanilla-glue": "0.1.0-alpha-2",
+ "@primer/octicons": "17.4.0",
"add-asset-webpack-plugin": "2.0.1",
"css-loader": "6.7.1",
"dropzone": "6.0.0-beta.2",
@@ -28,7 +29,7 @@
"monaco-editor-webpack-plugin": "7.0.1",
"pretty-ms": "8.0.0",
"sortablejs": "1.15.0",
- "swagger-ui-dist": "4.13.0",
+ "swagger-ui-dist": "4.13.2",
"tippy.js": "6.3.7",
"tributejs": "5.1.3",
"uint8-to-base64": "0.2.0",
@@ -37,22 +38,22 @@
"vue-calendar-heatmap": "0.8.4",
"vue-loader": "15.9.8",
"vue-template-compiler": "2.6.14",
- "webpack": "5.73.0",
+ "webpack": "5.74.0",
"webpack-cli": "4.10.0",
- "workbox-routing": "6.5.3",
- "workbox-strategies": "6.5.3",
+ "workbox-routing": "6.5.4",
+ "workbox-strategies": "6.5.4",
"worker-loader": "3.0.8",
"wrap-ansi": "8.0.1"
},
"devDependencies": {
"@happy-dom/jest-environment": "6.0.4",
- "@stoplight/spectral-cli": "6.4.1",
- "eslint": "8.20.0",
+ "@stoplight/spectral-cli": "6.5.0",
+ "eslint": "8.21.0",
"eslint-plugin-import": "2.26.0",
"eslint-plugin-jquery": "1.5.1",
- "eslint-plugin-sonarjs": "0.13.0",
+ "eslint-plugin-sonarjs": "0.14.0",
"eslint-plugin-unicorn": "43.0.2",
- "eslint-plugin-vue": "9.2.0",
+ "eslint-plugin-vue": "9.3.0",
"jest": "28.1.3",
"jest-extended": "3.0.1",
"markdownlint-cli": "0.32.1",
@@ -60,7 +61,7 @@
"stylelint": "14.9.1",
"stylelint-config-standard": "26.0.0",
"svgo": "2.8.0",
- "updates": "13.1.2"
+ "updates": "13.1.4"
},
"browserslist": [
"defaults",
diff --git a/public/img/svg/fontawesome-send.svg b/public/img/svg/fontawesome-send.svg
new file mode 100644
index 000000000000..b1170fd9e7c6
--- /dev/null
+++ b/public/img/svg/fontawesome-send.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/gitea-exclamation.svg b/public/img/svg/gitea-exclamation.svg
new file mode 100644
index 000000000000..d6c86136b31c
--- /dev/null
+++ b/public/img/svg/gitea-exclamation.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/gitea-pub.svg b/public/img/svg/gitea-pub.svg
new file mode 100644
index 000000000000..4a750c7082ed
--- /dev/null
+++ b/public/img/svg/gitea-pub.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-cache.svg b/public/img/svg/octicon-cache.svg
new file mode 100644
index 000000000000..20b14138d910
--- /dev/null
+++ b/public/img/svg/octicon-cache.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-checkbox.svg b/public/img/svg/octicon-checkbox.svg
new file mode 100644
index 000000000000..f0313bc747fc
--- /dev/null
+++ b/public/img/svg/octicon-checkbox.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-command-palette.svg b/public/img/svg/octicon-command-palette.svg
new file mode 100644
index 000000000000..92fcd6314951
--- /dev/null
+++ b/public/img/svg/octicon-command-palette.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-git-merge-queue.svg b/public/img/svg/octicon-git-merge-queue.svg
new file mode 100644
index 000000000000..17d7767b058c
--- /dev/null
+++ b/public/img/svg/octicon-git-merge-queue.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-paperclip.svg b/public/img/svg/octicon-paperclip.svg
new file mode 100644
index 000000000000..ddae143818ff
--- /dev/null
+++ b/public/img/svg/octicon-paperclip.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-table.svg b/public/img/svg/octicon-table.svg
index 905b2bb9b4c2..5b80f78357b6 100644
--- a/public/img/svg/octicon-table.svg
+++ b/public/img/svg/octicon-table.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/public/img/svg/octicon-tasklist.svg b/public/img/svg/octicon-tasklist.svg
index 81e41a87ced5..41b7c90f6de4 100644
--- a/public/img/svg/octicon-tasklist.svg
+++ b/public/img/svg/octicon-tasklist.svg
@@ -1 +1 @@
-
\ No newline at end of file
+
\ No newline at end of file
diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go
index bb9a42e33dc9..cbf041a7e136 100644
--- a/routers/api/packages/api.go
+++ b/routers/api/packages/api.go
@@ -21,6 +21,7 @@ import (
"code.gitea.io/gitea/routers/api/packages/maven"
"code.gitea.io/gitea/routers/api/packages/npm"
"code.gitea.io/gitea/routers/api/packages/nuget"
+ "code.gitea.io/gitea/routers/api/packages/pub"
"code.gitea.io/gitea/routers/api/packages/pypi"
"code.gitea.io/gitea/routers/api/packages/rubygems"
"code.gitea.io/gitea/services/auth"
@@ -45,6 +46,7 @@ func Routes() *web.Route {
authMethods := []auth.Method{
&auth.OAuth2{},
&auth.Basic{},
+ &nuget.Auth{},
&conan.Auth{},
}
if setting.Service.EnableReverseProxyAuth {
@@ -155,12 +157,15 @@ func Routes() *web.Route {
})
})
r.Group("/generic", func() {
- r.Group("/{packagename}/{packageversion}/{filename}", func() {
- r.Get("", generic.DownloadPackageFile)
- r.Group("", func() {
- r.Put("", generic.UploadPackage)
- r.Delete("", generic.DeletePackage)
- }, reqPackageAccess(perm.AccessModeWrite))
+ r.Group("/{packagename}/{packageversion}", func() {
+ r.Delete("", reqPackageAccess(perm.AccessModeWrite), generic.DeletePackage)
+ r.Group("/{filename}", func() {
+ r.Get("", generic.DownloadPackageFile)
+ r.Group("", func() {
+ r.Put("", generic.UploadPackage)
+ r.Delete("", generic.DeletePackageFile)
+ }, reqPackageAccess(perm.AccessModeWrite))
+ })
})
})
r.Group("/helm", func() {
@@ -194,12 +199,26 @@ func Routes() *web.Route {
r.Group("/@{scope}/{id}", func() {
r.Get("", npm.PackageMetadata)
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
- r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
+ r.Group("/-/{version}/{filename}", func() {
+ r.Get("", npm.DownloadPackageFile)
+ r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
+ })
+ r.Group("/-rev/{revision}", func() {
+ r.Delete("", npm.DeletePackage)
+ r.Put("", npm.DeletePreview)
+ }, reqPackageAccess(perm.AccessModeWrite))
})
r.Group("/{id}", func() {
r.Get("", npm.PackageMetadata)
r.Put("", reqPackageAccess(perm.AccessModeWrite), npm.UploadPackage)
- r.Get("/-/{version}/{filename}", npm.DownloadPackageFile)
+ r.Group("/-/{version}/{filename}", func() {
+ r.Get("", npm.DownloadPackageFile)
+ r.Delete("/-rev/{revision}", reqPackageAccess(perm.AccessModeWrite), npm.DeletePackageVersion)
+ })
+ r.Group("/-rev/{revision}", func() {
+ r.Delete("", npm.DeletePackage)
+ r.Put("", npm.DeletePreview)
+ }, reqPackageAccess(perm.AccessModeWrite))
})
r.Group("/-/package/@{scope}/{id}/dist-tags", func() {
r.Get("", npm.ListPackageTags)
@@ -216,6 +235,20 @@ func Routes() *web.Route {
}, reqPackageAccess(perm.AccessModeWrite))
})
})
+ r.Group("/pub", func() {
+ r.Group("/api/packages", func() {
+ r.Group("/versions/new", func() {
+ r.Get("", pub.RequestUpload)
+ r.Post("/upload", pub.UploadPackageFile)
+ r.Get("/finalize/{id}/{version}", pub.FinalizePackage)
+ }, reqPackageAccess(perm.AccessModeWrite))
+ r.Group("/{id}", func() {
+ r.Get("", pub.EnumeratePackageVersions)
+ r.Get("/files/{version}", pub.DownloadPackageFile)
+ r.Get("/{version}", pub.PackageVersionMetadata)
+ })
+ })
+ })
r.Group("/pypi", func() {
r.Post("/", reqPackageAccess(perm.AccessModeWrite), pypi.UploadPackageFile)
r.Get("/files/{id}/{version}/{filename}", pypi.DownloadPackageFile)
diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go
index 319c9bcabc11..8beed3dbb729 100644
--- a/routers/api/packages/container/manifest.go
+++ b/routers/api/packages/container/manifest.go
@@ -312,6 +312,9 @@ func createPackageAndVersion(ctx context.Context, mci *manifestCreationInfo, met
return nil, err
}
+ // keep download count on overwrite
+ _pv.DownloadCount = pv.DownloadCount
+
if pv, err = packages_model.GetOrInsertVersion(ctx, _pv); err != nil {
log.Error("Error inserting package: %v", err)
return nil, err
diff --git a/routers/api/packages/generic/generic.go b/routers/api/packages/generic/generic.go
index 9a3a185d9da5..79e5afb03cae 100644
--- a/routers/api/packages/generic/generic.go
+++ b/routers/api/packages/generic/generic.go
@@ -31,22 +31,16 @@ func apiError(ctx *context.Context, status int, obj interface{}) {
// DownloadPackageFile serves the specific generic package.
func DownloadPackageFile(ctx *context.Context) {
- packageName, packageVersion, filename, err := sanitizeParameters(ctx)
- if err != nil {
- apiError(ctx, http.StatusBadRequest, err)
- return
- }
-
s, pf, err := packages_service.GetFileStreamByPackageNameAndVersion(
ctx,
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeGeneric,
- Name: packageName,
- Version: packageVersion,
+ Name: ctx.Params("packagename"),
+ Version: ctx.Params("packageversion"),
},
&packages_service.PackageFileInfo{
- Filename: filename,
+ Filename: ctx.Params("filename"),
},
)
if err != nil {
@@ -65,9 +59,17 @@ func DownloadPackageFile(ctx *context.Context) {
// UploadPackage uploads the specific generic package.
// Duplicated packages get rejected.
func UploadPackage(ctx *context.Context) {
- packageName, packageVersion, filename, err := sanitizeParameters(ctx)
- if err != nil {
- apiError(ctx, http.StatusBadRequest, err)
+ packageName := ctx.Params("packagename")
+ filename := ctx.Params("filename")
+
+ if !packageNameRegex.MatchString(packageName) || !filenameRegex.MatchString(filename) {
+ apiError(ctx, http.StatusBadRequest, errors.New("Invalid package name or filename"))
+ return
+ }
+
+ packageVersion := ctx.Params("packageversion")
+ if packageVersion != strings.TrimSpace(packageVersion) {
+ apiError(ctx, http.StatusBadRequest, errors.New("Invalid package version"))
return
}
@@ -88,7 +90,7 @@ func UploadPackage(ctx *context.Context) {
}
defer buf.Close()
- _, _, err = packages_service.CreatePackageAndAddFile(
+ _, _, err = packages_service.CreatePackageOrAddFileToExisting(
&packages_service.PackageCreationInfo{
PackageInfo: packages_service.PackageInfo{
Owner: ctx.Package.Owner,
@@ -107,8 +109,8 @@ func UploadPackage(ctx *context.Context) {
},
)
if err != nil {
- if err == packages_model.ErrDuplicatePackageVersion {
- apiError(ctx, http.StatusBadRequest, err)
+ if err == packages_model.ErrDuplicatePackageFile {
+ apiError(ctx, http.StatusConflict, err)
return
}
apiError(ctx, http.StatusInternalServerError, err)
@@ -120,19 +122,13 @@ func UploadPackage(ctx *context.Context) {
// DeletePackage deletes the specific generic package.
func DeletePackage(ctx *context.Context) {
- packageName, packageVersion, _, err := sanitizeParameters(ctx)
- if err != nil {
- apiError(ctx, http.StatusBadRequest, err)
- return
- }
-
- err = packages_service.RemovePackageVersionByNameAndVersion(
+ err := packages_service.RemovePackageVersionByNameAndVersion(
ctx.Doer,
&packages_service.PackageInfo{
Owner: ctx.Package.Owner,
PackageType: packages_model.TypeGeneric,
- Name: packageName,
- Version: packageVersion,
+ Name: ctx.Params("packagename"),
+ Version: ctx.Params("packageversion"),
},
)
if err != nil {
@@ -144,21 +140,50 @@ func DeletePackage(ctx *context.Context) {
return
}
- ctx.Status(http.StatusOK)
+ ctx.Status(http.StatusNoContent)
}
-func sanitizeParameters(ctx *context.Context) (string, string, string, error) {
- packageName := ctx.Params("packagename")
- filename := ctx.Params("filename")
+// DeletePackageFile deletes the specific file of a generic package.
+func DeletePackageFile(ctx *context.Context) {
+ pv, pf, err := func() (*packages_model.PackageVersion, *packages_model.PackageFile, error) {
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeGeneric, ctx.Params("packagename"), ctx.Params("packageversion"))
+ if err != nil {
+ return nil, nil, err
+ }
- if !packageNameRegex.MatchString(packageName) || !filenameRegex.MatchString(filename) {
- return "", "", "", errors.New("Invalid package name or filename")
+ pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, ctx.Params("filename"), packages_model.EmptyFileKey)
+ if err != nil {
+ return nil, nil, err
+ }
+
+ return pv, pf, nil
+ }()
+ if err != nil {
+ if err == packages_model.ErrPackageNotExist || err == packages_model.ErrPackageFileNotExist {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
}
- packageVersion := strings.TrimSpace(ctx.Params("packageversion"))
- if packageVersion == "" {
- return "", "", "", errors.New("Invalid package version")
+ pfs, err := packages_model.GetFilesByVersionID(ctx, pv.ID)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ if len(pfs) == 1 {
+ if err := packages_service.RemovePackageVersion(ctx.Doer, pv); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ } else {
+ if err := packages_service.DeletePackageFile(ctx, pf); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
}
- return packageName, packageVersion, filename, nil
+ ctx.Status(http.StatusNoContent)
}
diff --git a/routers/api/packages/maven/maven.go b/routers/api/packages/maven/maven.go
index bba4babf04f6..072a15f95c41 100644
--- a/routers/api/packages/maven/maven.go
+++ b/routers/api/packages/maven/maven.go
@@ -266,8 +266,9 @@ func UploadPackageFile(ctx *context.Context) {
PackageFileInfo: packages_service.PackageFileInfo{
Filename: params.Filename,
},
- Data: buf,
- IsLead: false,
+ Data: buf,
+ IsLead: false,
+ OverwriteExisting: params.IsMeta,
}
// If it's the package pom file extract the metadata
diff --git a/routers/api/packages/npm/npm.go b/routers/api/packages/npm/npm.go
index 152edc681a04..d5ba70f9645b 100644
--- a/routers/api/packages/npm/npm.go
+++ b/routers/api/packages/npm/npm.go
@@ -164,6 +164,63 @@ func UploadPackage(ctx *context.Context) {
ctx.Status(http.StatusCreated)
}
+// DeletePreview does nothing
+// The client tells the server what package version it knows about after deleting a version.
+func DeletePreview(ctx *context.Context) {
+ ctx.Status(http.StatusOK)
+}
+
+// DeletePackageVersion deletes the package version
+func DeletePackageVersion(ctx *context.Context) {
+ packageName := packageNameFromParams(ctx)
+ packageVersion := ctx.Params("version")
+
+ err := packages_service.RemovePackageVersionByNameAndVersion(
+ ctx.Doer,
+ &packages_service.PackageInfo{
+ Owner: ctx.Package.Owner,
+ PackageType: packages_model.TypeNpm,
+ Name: packageName,
+ Version: packageVersion,
+ },
+ )
+ if err != nil {
+ if err == packages_model.ErrPackageNotExist {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.Status(http.StatusOK)
+}
+
+// DeletePackage deletes the package and all versions
+func DeletePackage(ctx *context.Context) {
+ packageName := packageNameFromParams(ctx)
+
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypeNpm, packageName)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ if len(pvs) == 0 {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+
+ for _, pv := range pvs {
+ if err := packages_service.RemovePackageVersion(ctx.Doer, pv); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ }
+
+ ctx.Status(http.StatusOK)
+}
+
// ListPackageTags returns all tags for a package
func ListPackageTags(ctx *context.Context) {
packageName := packageNameFromParams(ctx)
diff --git a/routers/api/packages/nuget/auth.go b/routers/api/packages/nuget/auth.go
new file mode 100644
index 000000000000..26a5b9018931
--- /dev/null
+++ b/routers/api/packages/nuget/auth.go
@@ -0,0 +1,45 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package nuget
+
+import (
+ "net/http"
+
+ "code.gitea.io/gitea/models"
+ user_model "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/timeutil"
+ "code.gitea.io/gitea/services/auth"
+)
+
+type Auth struct{}
+
+func (a *Auth) Name() string {
+ return "nuget"
+}
+
+// https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters
+func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User {
+ token, err := models.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey"))
+ if err != nil {
+ if !(models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err)) {
+ log.Error("GetAccessTokenBySHA: %v", err)
+ }
+ return nil
+ }
+
+ u, err := user_model.GetUserByID(token.UID)
+ if err != nil {
+ log.Error("GetUserByID: %v", err)
+ return nil
+ }
+
+ token.UpdatedUnix = timeutil.TimeStampNow()
+ if err := models.UpdateAccessToken(token); err != nil {
+ log.Error("UpdateAccessToken: %v", err)
+ }
+
+ return u
+}
diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go
index b7667a32225a..81ea28bcad49 100644
--- a/routers/api/packages/nuget/nuget.go
+++ b/routers/api/packages/nuget/nuget.go
@@ -102,7 +102,7 @@ func RegistrationLeaf(ctx *context.Context) {
packageName := ctx.Params("id")
packageVersion := strings.TrimSuffix(ctx.Params("version"), ".json")
- pv, err := packages_model.GetVersionByNameAndVersion(db.DefaultContext, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypeNuGet, packageName, packageVersion)
if err != nil {
if err == packages_model.ErrPackageNotExist {
apiError(ctx, http.StatusNotFound, err)
@@ -217,7 +217,7 @@ func UploadPackage(ctx *context.Context) {
)
if err != nil {
if err == packages_model.ErrDuplicatePackageVersion {
- apiError(ctx, http.StatusBadRequest, err)
+ apiError(ctx, http.StatusConflict, err)
return
}
apiError(ctx, http.StatusInternalServerError, err)
@@ -274,7 +274,7 @@ func UploadSymbolPackage(ctx *context.Context) {
case packages_model.ErrPackageNotExist:
apiError(ctx, http.StatusNotFound, err)
case packages_model.ErrDuplicatePackageFile:
- apiError(ctx, http.StatusBadRequest, err)
+ apiError(ctx, http.StatusConflict, err)
default:
apiError(ctx, http.StatusInternalServerError, err)
}
@@ -299,7 +299,7 @@ func UploadSymbolPackage(ctx *context.Context) {
if err != nil {
switch err {
case packages_model.ErrDuplicatePackageFile:
- apiError(ctx, http.StatusBadRequest, err)
+ apiError(ctx, http.StatusConflict, err)
default:
apiError(ctx, http.StatusInternalServerError, err)
}
@@ -414,4 +414,6 @@ func DeletePackage(ctx *context.Context) {
}
apiError(ctx, http.StatusInternalServerError, err)
}
+
+ ctx.Status(http.StatusNoContent)
}
diff --git a/routers/api/packages/pub/pub.go b/routers/api/packages/pub/pub.go
new file mode 100644
index 000000000000..470f4462388a
--- /dev/null
+++ b/routers/api/packages/pub/pub.go
@@ -0,0 +1,275 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package pub
+
+import (
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "sort"
+ "strings"
+ "time"
+
+ packages_model "code.gitea.io/gitea/models/packages"
+ "code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
+ packages_module "code.gitea.io/gitea/modules/packages"
+ pub_module "code.gitea.io/gitea/modules/packages/pub"
+ "code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/routers/api/packages/helper"
+ packages_service "code.gitea.io/gitea/services/packages"
+)
+
+func jsonResponse(ctx *context.Context, status int, obj interface{}) {
+ resp := ctx.Resp
+ resp.Header().Set("Content-Type", "application/vnd.pub.v2+json")
+ resp.WriteHeader(status)
+ if err := json.NewEncoder(resp).Encode(obj); err != nil {
+ log.Error("JSON encode: %v", err)
+ }
+}
+
+func apiError(ctx *context.Context, status int, obj interface{}) {
+ type Error struct {
+ Code string `json:"code"`
+ Message string `json:"message"`
+ }
+ type ErrorWrapper struct {
+ Error Error `json:"error"`
+ }
+
+ helper.LogAndProcessError(ctx, status, obj, func(message string) {
+ jsonResponse(ctx, status, ErrorWrapper{
+ Error: Error{
+ Code: http.StatusText(status),
+ Message: message,
+ },
+ })
+ })
+}
+
+type packageVersions struct {
+ Name string `json:"name"`
+ Latest *versionMetadata `json:"latest"`
+ Versions []*versionMetadata `json:"versions"`
+}
+
+type versionMetadata struct {
+ Version string `json:"version"`
+ ArchiveURL string `json:"archive_url"`
+ Published time.Time `json:"published"`
+ Pubspec interface{} `json:"pubspec,omitempty"`
+}
+
+func packageDescriptorToMetadata(baseURL string, pd *packages_model.PackageDescriptor) *versionMetadata {
+ return &versionMetadata{
+ Version: pd.Version.Version,
+ ArchiveURL: fmt.Sprintf("%s/files/%s.tar.gz", baseURL, url.PathEscape(pd.Version.Version)),
+ Published: time.Unix(int64(pd.Version.CreatedUnix), 0),
+ Pubspec: pd.Metadata.(*pub_module.Metadata).Pubspec,
+ }
+}
+
+func baseURL(ctx *context.Context) string {
+ return setting.AppURL + "api/packages/" + ctx.Package.Owner.Name + "/pub/api/packages"
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#list-all-versions-of-a-package
+func EnumeratePackageVersions(ctx *context.Context) {
+ packageName := ctx.Params("id")
+
+ pvs, err := packages_model.GetVersionsByPackageName(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ if len(pvs) == 0 {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+
+ pds, err := packages_model.GetPackageDescriptors(ctx, pvs)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ sort.Slice(pds, func(i, j int) bool {
+ return pds[i].SemVer.LessThan(pds[j].SemVer)
+ })
+
+ baseURL := fmt.Sprintf("%s/%s", baseURL(ctx), url.PathEscape(pds[0].Package.Name))
+
+ versions := make([]*versionMetadata, 0, len(pds))
+ for _, pd := range pds {
+ versions = append(versions, packageDescriptorToMetadata(baseURL, pd))
+ }
+
+ jsonResponse(ctx, http.StatusOK, &packageVersions{
+ Name: pds[0].Package.Name,
+ Latest: packageDescriptorToMetadata(baseURL, pds[0]),
+ Versions: versions,
+ })
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-inspect-a-specific-version-of-a-package
+func PackageVersionMetadata(ctx *context.Context) {
+ packageName := ctx.Params("id")
+ packageVersion := ctx.Params("version")
+
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
+ if err != nil {
+ if err == packages_model.ErrPackageNotExist {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ pd, err := packages_model.GetPackageDescriptor(ctx, pv)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ jsonResponse(ctx, http.StatusOK, packageDescriptorToMetadata(
+ fmt.Sprintf("%s/%s", baseURL(ctx), url.PathEscape(pd.Package.Name)),
+ pd,
+ ))
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages
+func RequestUpload(ctx *context.Context) {
+ type UploadRequest struct {
+ URL string `json:"url"`
+ Fields map[string]string `json:"fields"`
+ }
+
+ jsonResponse(ctx, http.StatusOK, UploadRequest{
+ URL: baseURL(ctx) + "/versions/new/upload",
+ Fields: make(map[string]string),
+ })
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages
+func UploadPackageFile(ctx *context.Context) {
+ file, _, err := ctx.Req.FormFile("file")
+ if err != nil {
+ apiError(ctx, http.StatusBadRequest, err)
+ return
+ }
+ defer file.Close()
+
+ buf, err := packages_module.CreateHashedBufferFromReader(file, 32*1024*1024)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ defer buf.Close()
+
+ pck, err := pub_module.ParsePackage(buf)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ if _, err := buf.Seek(0, io.SeekStart); err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ _, _, err = packages_service.CreatePackageAndAddFile(
+ &packages_service.PackageCreationInfo{
+ PackageInfo: packages_service.PackageInfo{
+ Owner: ctx.Package.Owner,
+ PackageType: packages_model.TypePub,
+ Name: pck.Name,
+ Version: pck.Version,
+ },
+ SemverCompatible: true,
+ Creator: ctx.Doer,
+ Metadata: pck.Metadata,
+ },
+ &packages_service.PackageFileCreationInfo{
+ PackageFileInfo: packages_service.PackageFileInfo{
+ Filename: strings.ToLower(pck.Version + ".tar.gz"),
+ },
+ Data: buf,
+ IsLead: true,
+ },
+ )
+ if err != nil {
+ if err == packages_model.ErrDuplicatePackageVersion {
+ apiError(ctx, http.StatusBadRequest, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ ctx.Resp.Header().Set("Location", fmt.Sprintf("%s/versions/new/finalize/%s/%s", baseURL(ctx), url.PathEscape(pck.Name), url.PathEscape(pck.Version)))
+ ctx.Status(http.StatusNoContent)
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#publishing-packages
+func FinalizePackage(ctx *context.Context) {
+ packageName := ctx.Params("id")
+ packageVersion := ctx.Params("version")
+
+ _, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
+ if err != nil {
+ if err == packages_model.ErrPackageNotExist {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ type Success struct {
+ Message string `json:"message"`
+ }
+ type SuccessWrapper struct {
+ Success Success `json:"success"`
+ }
+
+ jsonResponse(ctx, http.StatusOK, SuccessWrapper{Success{}})
+}
+
+// https://github.com/dart-lang/pub/blob/master/doc/repository-spec-v2.md#deprecated-download-a-specific-version-of-a-package
+func DownloadPackageFile(ctx *context.Context) {
+ packageName := ctx.Params("id")
+ packageVersion := strings.TrimSuffix(ctx.Params("version"), ".tar.gz")
+
+ pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.TypePub, packageName, packageVersion)
+ if err != nil {
+ if err == packages_model.ErrPackageNotExist {
+ apiError(ctx, http.StatusNotFound, err)
+ return
+ }
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ pd, err := packages_model.GetPackageDescriptor(ctx, pv)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+
+ pf := pd.Files[0].File
+
+ s, _, err := packages_service.GetPackageFileStream(ctx, pf)
+ if err != nil {
+ apiError(ctx, http.StatusInternalServerError, err)
+ return
+ }
+ defer s.Close()
+
+ ctx.ServeStream(s, pf.Name)
+}
diff --git a/routers/api/v1/packages/package.go b/routers/api/v1/packages/package.go
index 5a9c93b3ca06..2c023891022a 100644
--- a/routers/api/v1/packages/package.go
+++ b/routers/api/v1/packages/package.go
@@ -41,7 +41,7 @@ func ListPackages(ctx *context.APIContext) {
// in: query
// description: package type filter
// type: string
- // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pypi, rubygems]
+ // enum: [composer, conan, container, generic, helm, maven, npm, nuget, pub, pypi, rubygems]
// - name: q
// in: query
// description: name filter
diff --git a/routers/api/v1/repo/issue.go b/routers/api/v1/repo/issue.go
index ddad18ef62ca..08e3e037417c 100644
--- a/routers/api/v1/repo/issue.go
+++ b/routers/api/v1/repo/issue.go
@@ -282,7 +282,7 @@ func SearchIssues(ctx *context.APIContext) {
}
}
- ctx.SetLinkHeader(int(filteredCount), setting.UI.IssuePagingNum)
+ ctx.SetLinkHeader(int(filteredCount), limit)
ctx.SetTotalCountHeader(filteredCount)
ctx.JSON(http.StatusOK, convert.ToAPIIssueList(issues))
}
diff --git a/routers/api/v1/repo/wiki.go b/routers/api/v1/repo/wiki.go
index a3a590492500..d423bddbbd4d 100644
--- a/routers/api/v1/repo/wiki.go
+++ b/routers/api/v1/repo/wiki.go
@@ -427,9 +427,9 @@ func ListPageRevisions(ctx *context.APIContext) {
}
// get Commit Count
- commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
+ commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
if err != nil {
- ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRangeNoFollow", err)
+ ctx.Error(http.StatusInternalServerError, "CommitsByFileAndRange", err)
return
}
diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go
index f0dc595ad5cc..ba008f587c69 100644
--- a/routers/api/v1/utils/hook.go
+++ b/routers/api/v1/utils/hook.go
@@ -15,7 +15,6 @@ import (
"code.gitea.io/gitea/modules/json"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/util"
- "code.gitea.io/gitea/routers/utils"
webhook_service "code.gitea.io/gitea/services/webhook"
)
@@ -141,14 +140,15 @@ func addHook(ctx *context.APIContext, form *api.CreateHookOption, orgID, repoID
ctx.Error(http.StatusUnprocessableEntity, "", "Missing config option: channel")
return nil, false
}
+ channel = strings.TrimSpace(channel)
- if !utils.IsValidSlackChannel(channel) {
+ if !webhook_service.IsValidSlackChannel(channel) {
ctx.Error(http.StatusBadRequest, "", "Invalid slack channel name")
return nil, false
}
meta, err := json.Marshal(&webhook_service.SlackMeta{
- Channel: strings.TrimSpace(channel),
+ Channel: channel,
Username: form.Config["username"],
IconURL: form.Config["icon_url"],
Color: form.Config["color"],
diff --git a/routers/init.go b/routers/init.go
index e640ca48453b..612fc5a83dbb 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -100,10 +100,8 @@ func GlobalInitInstalled(ctx context.Context) {
log.Fatal("Gitea is not installed")
}
- mustInitCtx(ctx, git.InitOnceWithSync)
+ mustInitCtx(ctx, git.InitFull)
log.Info("Git Version: %s (home: %s)", git.VersionInfo(), git.HomeDir())
-
- git.CheckLFSVersion()
log.Info("AppPath: %s", setting.AppPath)
log.Info("AppWorkPath: %s", setting.AppWorkPath)
log.Info("Custom path: %s", setting.CustomPath)
diff --git a/routers/private/mail.go b/routers/private/mail.go
index 966a83816800..e858992aee13 100644
--- a/routers/private/mail.go
+++ b/routers/private/mail.go
@@ -9,6 +9,7 @@ import (
"net/http"
"strconv"
+ "code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/json"
@@ -59,7 +60,7 @@ func SendEmail(ctx *context.PrivateContext) {
}
}
} else {
- err := user_model.IterateUser(func(user *user_model.User) error {
+ err := db.IterateObjects(ctx, func(user *user_model.User) error {
if len(user.Email) > 0 && user.IsActive {
emails = append(emails, user.Email)
}
diff --git a/routers/utils/utils.go b/routers/utils/utils.go
index f15bc1e62e4b..66eaa1d9ce17 100644
--- a/routers/utils/utils.go
+++ b/routers/utils/utils.go
@@ -20,25 +20,6 @@ func RemoveUsernameParameterSuffix(name string) string {
return name
}
-// IsValidSlackChannel validates a channel name conforms to what slack expects.
-// It makes sure a channel name cannot be empty and invalid ( only an # )
-func IsValidSlackChannel(channelName string) bool {
- switch len(strings.TrimSpace(channelName)) {
- case 0:
- return false
- case 1:
- // Keep default behaviour where a channel name is still
- // valid without an #
- // But if it contains only an #, it should be regarded as
- // invalid
- if channelName[0] == '#' {
- return false
- }
- }
-
- return true
-}
-
// SanitizeFlashErrorString will sanitize a flash error string
func SanitizeFlashErrorString(x string) string {
return strings.ReplaceAll(html.EscapeString(x), "\n", " ")
diff --git a/routers/utils/utils_test.go b/routers/utils/utils_test.go
index f49ed77b6fc0..42cf948e3091 100644
--- a/routers/utils/utils_test.go
+++ b/routers/utils/utils_test.go
@@ -18,23 +18,6 @@ func TestRemoveUsernameParameterSuffix(t *testing.T) {
assert.Equal(t, "", RemoveUsernameParameterSuffix(""))
}
-func TestIsValidSlackChannel(t *testing.T) {
- tt := []struct {
- channelName string
- expected bool
- }{
- {"gitea", true},
- {" ", false},
- {"#", false},
- {"gitea ", true},
- {" gitea", true},
- }
-
- for _, v := range tt {
- assert.Equal(t, v.expected, IsValidSlackChannel(v.channelName))
- }
-}
-
func TestIsExternalURL(t *testing.T) {
setting.AppURL = "https://try.gitea.io/"
type test struct {
diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go
index ebe5066d2cf6..c773034c533f 100644
--- a/routers/web/admin/admin.go
+++ b/routers/web/admin/admin.go
@@ -257,6 +257,7 @@ func Config(ctx *context.Context) {
ctx.Data["ScriptType"] = setting.ScriptType
ctx.Data["ReverseProxyAuthUser"] = setting.ReverseProxyAuthUser
ctx.Data["ReverseProxyAuthEmail"] = setting.ReverseProxyAuthEmail
+ ctx.Data["ReverseProxyAuthFullName"] = setting.ReverseProxyAuthFullName
ctx.Data["SSH"] = setting.SSH
ctx.Data["LFS"] = setting.LFS
diff --git a/routers/web/admin/users_test.go b/routers/web/admin/users_test.go
index e63367ccf2cd..da67cd5cb45d 100644
--- a/routers/web/admin/users_test.go
+++ b/routers/web/admin/users_test.go
@@ -25,7 +25,7 @@ func TestNewUserPost_MustChangePassword(t *testing.T) {
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true,
ID: 2,
- }).(*user_model.User)
+ })
ctx.Doer = u
@@ -62,7 +62,7 @@ func TestNewUserPost_MustChangePasswordFalse(t *testing.T) {
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true,
ID: 2,
- }).(*user_model.User)
+ })
ctx.Doer = u
@@ -99,7 +99,7 @@ func TestNewUserPost_InvalidEmail(t *testing.T) {
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true,
ID: 2,
- }).(*user_model.User)
+ })
ctx.Doer = u
@@ -129,7 +129,7 @@ func TestNewUserPost_VisibilityDefaultPublic(t *testing.T) {
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true,
ID: 2,
- }).(*user_model.User)
+ })
ctx.Doer = u
@@ -167,7 +167,7 @@ func TestNewUserPost_VisibilityPrivate(t *testing.T) {
u := unittest.AssertExistsAndLoadBean(t, &user_model.User{
IsAdmin: true,
ID: 2,
- }).(*user_model.User)
+ })
ctx.Doer = u
diff --git a/routers/web/auth/auth.go b/routers/web/auth/auth.go
index 610e4d29045d..8a4c12d57b57 100644
--- a/routers/web/auth/auth.go
+++ b/routers/web/auth/auth.go
@@ -18,6 +18,7 @@ import (
"code.gitea.io/gitea/modules/eventsource"
"code.gitea.io/gitea/modules/hcaptcha"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/mcaptcha"
"code.gitea.io/gitea/modules/password"
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/session"
@@ -414,6 +415,8 @@ func SignUp(ctx *context.Context) {
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["PageIsSignUp"] = true
// Show Disabled Registration message if DisableRegistration or AllowOnlyExternalRegistration options are true
@@ -435,6 +438,8 @@ func SignUpPost(ctx *context.Context) {
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["PageIsSignUp"] = true
// Permission denied if DisableRegistration or AllowOnlyExternalRegistration options are true
@@ -458,6 +463,8 @@ func SignUpPost(ctx *context.Context) {
valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse)
case setting.HCaptcha:
valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse)
+ case setting.MCaptcha:
+ valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse)
default:
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType))
return
diff --git a/routers/web/auth/linkaccount.go b/routers/web/auth/linkaccount.go
index a2d76e9c5a34..4f3f2062b689 100644
--- a/routers/web/auth/linkaccount.go
+++ b/routers/web/auth/linkaccount.go
@@ -16,6 +16,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/hcaptcha"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/mcaptcha"
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
@@ -40,6 +41,8 @@ func LinkAccount(ctx *context.Context) {
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["AllowOnlyInternalRegistration"] = setting.Service.AllowOnlyInternalRegistration
ctx.Data["ShowRegistrationButton"] = false
@@ -96,6 +99,8 @@ func LinkAccountPostSignIn(ctx *context.Context) {
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false
@@ -195,6 +200,8 @@ func LinkAccountPostRegister(ctx *context.Context) {
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["DisableRegistration"] = setting.Service.DisableRegistration
ctx.Data["ShowRegistrationButton"] = false
@@ -233,6 +240,8 @@ func LinkAccountPostRegister(ctx *context.Context) {
valid, err = recaptcha.Verify(ctx, form.GRecaptchaResponse)
case setting.HCaptcha:
valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse)
+ case setting.MCaptcha:
+ valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse)
default:
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType))
return
diff --git a/routers/web/auth/oauth_test.go b/routers/web/auth/oauth_test.go
index 57f2477dba3e..48400846d245 100644
--- a/routers/web/auth/oauth_test.go
+++ b/routers/web/auth/oauth_test.go
@@ -60,7 +60,7 @@ func TestNewAccessTokenResponse_OIDCToken(t *testing.T) {
assert.Empty(t, oidcToken.Email)
assert.False(t, oidcToken.EmailVerified)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
grants, err = auth.GetOAuth2GrantsByUserID(db.DefaultContext, user.ID)
assert.NoError(t, err)
assert.Len(t, grants, 1)
diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go
index 32ae91da47b8..3b1065189d9d 100644
--- a/routers/web/auth/openid.go
+++ b/routers/web/auth/openid.go
@@ -15,6 +15,7 @@ import (
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/hcaptcha"
"code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/mcaptcha"
"code.gitea.io/gitea/modules/recaptcha"
"code.gitea.io/gitea/modules/session"
"code.gitea.io/gitea/modules/setting"
@@ -341,6 +342,8 @@ func RegisterOpenID(ctx *context.Context) {
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
ctx.Data["RecaptchaURL"] = setting.Service.RecaptchaURL
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["OpenID"] = oid
userName, _ := ctx.Session.Get("openid_determined_username").(string)
if userName != "" {
@@ -372,6 +375,8 @@ func RegisterOpenIDPost(ctx *context.Context) {
ctx.Data["CaptchaType"] = setting.Service.CaptchaType
ctx.Data["RecaptchaSitekey"] = setting.Service.RecaptchaSitekey
ctx.Data["HcaptchaSitekey"] = setting.Service.HcaptchaSitekey
+ ctx.Data["McaptchaSitekey"] = setting.Service.McaptchaSitekey
+ ctx.Data["McaptchaURL"] = setting.Service.McaptchaURL
ctx.Data["OpenID"] = oid
if setting.Service.AllowOnlyInternalRegistration {
@@ -397,6 +402,12 @@ func RegisterOpenIDPost(ctx *context.Context) {
return
}
valid, err = hcaptcha.Verify(ctx, form.HcaptchaResponse)
+ case setting.MCaptcha:
+ if err := ctx.Req.ParseForm(); err != nil {
+ ctx.ServerError("", err)
+ return
+ }
+ valid, err = mcaptcha.Verify(ctx, form.McaptchaResponse)
default:
ctx.ServerError("Unknown Captcha Type", fmt.Errorf("Unknown Captcha Type: %s", setting.Service.CaptchaType))
return
diff --git a/routers/web/repo/blame.go b/routers/web/repo/blame.go
index 06c43aec19fb..c53a53b47193 100644
--- a/routers/web/repo/blame.go
+++ b/routers/web/repo/blame.go
@@ -40,7 +40,7 @@ type blameRow struct {
CommitMessage string
CommitSince gotemplate.HTML
Code gotemplate.HTML
- EscapeStatus charset.EscapeStatus
+ EscapeStatus *charset.EscapeStatus
}
// RefBlame render blame page
@@ -235,7 +235,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
}
lines := make([]string, 0)
rows := make([]*blameRow, 0)
- escapeStatus := charset.EscapeStatus{}
+ escapeStatus := &charset.EscapeStatus{}
i := 0
commitCnt := 0
@@ -280,7 +280,7 @@ func renderBlame(ctx *context.Context, blameParts []git.BlamePart, commitNames m
fileName := fmt.Sprintf("%v", ctx.Data["FileName"])
line = highlight.Code(fileName, language, line)
- br.EscapeStatus, line = charset.EscapeControlString(line)
+ br.EscapeStatus, line = charset.EscapeControlHTML(line, ctx.Locale)
br.Code = gotemplate.HTML(line)
rows = append(rows, br)
escapeStatus = escapeStatus.Or(br.EscapeStatus)
diff --git a/routers/web/repo/http.go b/routers/web/repo/http.go
index 6a85bca16b2f..5aa2bcd13471 100644
--- a/routers/web/repo/http.go
+++ b/routers/web/repo/http.go
@@ -474,11 +474,12 @@ func serviceRPC(ctx gocontext.Context, h serviceHandler, service string) {
cmd := git.NewCommand(h.r.Context(), service, "--stateless-rpc", h.dir)
cmd.SetDescription(fmt.Sprintf("%s %s %s [repo_path: %s]", git.GitExecutable, service, "--stateless-rpc", h.dir))
if err := cmd.Run(&git.RunOpts{
- Dir: h.dir,
- Env: append(os.Environ(), h.environ...),
- Stdout: h.w,
- Stdin: reqBody,
- Stderr: &stderr,
+ Dir: h.dir,
+ Env: append(os.Environ(), h.environ...),
+ Stdout: h.w,
+ Stdin: reqBody,
+ Stderr: &stderr,
+ UseContextTimeout: true,
}); err != nil {
if err.Error() != "signal: killed" {
log.Error("Fail to serve RPC(%s) in %s: %v - %s", service, h.dir, err, stderr.String())
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index e6f9529e31e8..ad25a94e13b1 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -133,7 +133,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
var (
assigneeID = ctx.FormInt64("assignee")
- posterID int64
+ posterID = ctx.FormInt64("poster")
mentionedID int64
reviewRequestedID int64
forceEmpty bool
@@ -291,6 +291,12 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
return
}
+ ctx.Data["Posters"], err = repo_model.GetIssuePosters(ctx, repo, isPullOption.IsTrue())
+ if err != nil {
+ ctx.ServerError("GetIssuePosters", err)
+ return
+ }
+
handleTeamMentions(ctx)
if ctx.Written() {
return
@@ -364,6 +370,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
ctx.Data["SortType"] = sortType
ctx.Data["MilestoneID"] = milestoneID
ctx.Data["AssigneeID"] = assigneeID
+ ctx.Data["PosterID"] = posterID
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["Keyword"] = keyword
if isShowClosed {
@@ -379,6 +386,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption uti
pager.AddParam(ctx, "labels", "SelectLabels")
pager.AddParam(ctx, "milestone", "MilestoneID")
pager.AddParam(ctx, "assignee", "AssigneeID")
+ pager.AddParam(ctx, "poster", "PosterID")
ctx.Data["Page"] = pager
}
diff --git a/routers/web/repo/lfs.go b/routers/web/repo/lfs.go
index 0e446f2de068..baec48bfea77 100644
--- a/routers/web/repo/lfs.go
+++ b/routers/web/repo/lfs.go
@@ -309,7 +309,7 @@ func LFSFileGet(ctx *context.Context) {
// Building code view blocks with line number on server side.
escapedContent := &bytes.Buffer{}
- ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, escapedContent)
+ ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, escapedContent, ctx.Locale)
var output bytes.Buffer
lines := strings.Split(escapedContent.String(), "\n")
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index 2a961c3cbc55..7c140a4e5991 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -510,6 +510,8 @@ func PrepareViewPullInfo(ctx *context.Context, issue *issues_model.Issue) *git.C
return nil
}
ctx.Data["GetCommitMessages"] = pull_service.GetSquashMergeCommitMessages(ctx, pull)
+ } else {
+ ctx.Data["GetCommitMessages"] = ""
}
sha, err := baseGitRepo.GetRefCommitID(pull.GetGitRefName())
diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go
index 6a9c6b9bbace..72ffda7e0147 100644
--- a/routers/web/repo/view.go
+++ b/routers/web/repo/view.go
@@ -328,35 +328,31 @@ func renderReadmeFile(ctx *context.Context, readmeFile *namedBlob, readmeTreelin
if markupType := markup.Type(readmeFile.name); markupType != "" {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
- var result strings.Builder
- err := markup.Render(&markup.RenderContext{
+
+ ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
RelativePath: path.Join(ctx.Repo.TreePath, readmeFile.name), // ctx.Repo.TreePath is the directory not the Readme so we must append the Readme filename (and path).
URLPrefix: readmeTreelink,
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
GitRepo: ctx.Repo.GitRepo,
- }, rd, &result)
+ }, rd)
if err != nil {
- log.Error("Render failed: %v then fallback", err)
+ log.Error("Render failed for %s in %-v: %v Falling back to rendering source", readmeFile.name, ctx.Repo.Repository, err)
buf := &bytes.Buffer{}
- ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
+ ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = strings.ReplaceAll(
gotemplate.HTMLEscapeString(buf.String()), "\n", ` `,
)
- } else {
- ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
}
} else {
ctx.Data["IsRenderedHTML"] = true
buf := &bytes.Buffer{}
- ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, buf)
+ ctx.Data["EscapeStatus"], err = charset.EscapeControlReader(rd, &charset.BreakWriter{Writer: buf}, ctx.Locale, charset.RuneNBSP)
if err != nil {
log.Error("Read failed: %v", err)
}
- ctx.Data["FileContent"] = strings.ReplaceAll(
- gotemplate.HTMLEscapeString(buf.String()), "\n", ` `,
- )
+ ctx.Data["FileContent"] = buf.String()
}
}
@@ -498,32 +494,30 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
if markupType != "" && !shouldRenderSource {
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
- var result strings.Builder
if !detected {
markupType = ""
}
metas := ctx.Repo.Repository.ComposeDocumentMetas()
metas["BranchNameSubURL"] = ctx.Repo.BranchNameSubURL()
- err := markup.Render(&markup.RenderContext{
+ ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
Type: markupType,
RelativePath: ctx.Repo.TreePath,
URLPrefix: path.Dir(treeLink),
Metas: metas,
GitRepo: ctx.Repo.GitRepo,
- }, rd, &result)
+ }, rd)
if err != nil {
ctx.ServerError("Render", err)
return
}
// to prevent iframe load third-party url
ctx.Resp.Header().Add("Content-Security-Policy", "frame-src 'self'")
- ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
} else if readmeExist && !shouldRenderSource {
buf := &bytes.Buffer{}
ctx.Data["IsRenderedHTML"] = true
- ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf)
+ ctx.Data["EscapeStatus"], _ = charset.EscapeControlReader(rd, buf, ctx.Locale)
ctx.Data["FileContent"] = strings.ReplaceAll(
gotemplate.HTMLEscapeString(buf.String()), "\n", ` `,
@@ -570,12 +564,13 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
log.Error("highlight.File failed, fallback to plain text: %v", err)
fileContent = highlight.PlainText(buf)
}
- status, _ := charset.EscapeControlReader(bytes.NewReader(buf), io.Discard)
- ctx.Data["EscapeStatus"] = status
- statuses := make([]charset.EscapeStatus, len(fileContent))
+ status := &charset.EscapeStatus{}
+ statuses := make([]*charset.EscapeStatus, len(fileContent))
for i, line := range fileContent {
- statuses[i], fileContent[i] = charset.EscapeControlString(line)
+ statuses[i], fileContent[i] = charset.EscapeControlHTML(line, ctx.Locale)
+ status = status.Or(statuses[i])
}
+ ctx.Data["EscapeStatus"] = status
ctx.Data["FileContent"] = fileContent
ctx.Data["LineEscapeStatus"] = statuses
}
@@ -613,20 +608,17 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
rd := io.MultiReader(bytes.NewReader(buf), dataRc)
ctx.Data["IsMarkup"] = true
ctx.Data["MarkupType"] = markupType
- var result strings.Builder
- err := markup.Render(&markup.RenderContext{
+ ctx.Data["EscapeStatus"], ctx.Data["FileContent"], err = markupRender(ctx, &markup.RenderContext{
Ctx: ctx,
RelativePath: ctx.Repo.TreePath,
URLPrefix: path.Dir(treeLink),
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
GitRepo: ctx.Repo.GitRepo,
- }, rd, &result)
+ }, rd)
if err != nil {
ctx.ServerError("Render", err)
return
}
-
- ctx.Data["EscapeStatus"], ctx.Data["FileContent"] = charset.EscapeControlString(result.String())
}
}
@@ -645,6 +637,23 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry, treeLink, rawLink st
}
}
+func markupRender(ctx *context.Context, renderCtx *markup.RenderContext, input io.Reader) (escaped *charset.EscapeStatus, output string, err error) {
+ markupRd, markupWr := io.Pipe()
+ defer markupWr.Close()
+ done := make(chan struct{})
+ go func() {
+ sb := &strings.Builder{}
+ // We allow NBSP here this is rendered
+ escaped, _ = charset.EscapeControlReader(markupRd, sb, ctx.Locale, charset.RuneNBSP)
+ output = sb.String()
+ close(done)
+ }()
+ err = markup.Render(renderCtx, input, markupWr)
+ _ = markupWr.CloseWithError(err)
+ <-done
+ return escaped, output, err
+}
+
func safeURL(address string) string {
u, err := url.Parse(address)
if err != nil {
diff --git a/routers/web/repo/webhook.go b/routers/web/repo/webhook.go
index a9b14ee21f45..d4419a1e1095 100644
--- a/routers/web/repo/webhook.go
+++ b/routers/web/repo/webhook.go
@@ -185,14 +185,22 @@ func ParseHookEvent(form forms.WebhookForm) *webhook.HookEvent {
}
}
-// GiteaHooksNewPost response for creating Gitea webhook
-func GiteaHooksNewPost(ctx *context.Context) {
- form := web.GetForm(ctx).(*forms.NewWebhookForm)
+type webhookCreationParams struct {
+ URL string
+ ContentType webhook.HookContentType
+ Secret string
+ HTTPMethod string
+ WebhookForm forms.WebhookForm
+ Type string
+ Meta interface{}
+}
+
+func createWebhook(ctx *context.Context, params webhookCreationParams) {
ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
ctx.Data["PageIsSettingsHooks"] = true
ctx.Data["PageIsSettingsHooksNew"] = true
ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.GITEA
+ ctx.Data["HookType"] = params.Type
orCtx, err := getOrgRepoCtx(ctx)
if err != nil {
@@ -206,20 +214,25 @@ func GiteaHooksNewPost(ctx *context.Context) {
return
}
- contentType := webhook.ContentTypeJSON
- if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
- contentType = webhook.ContentTypeForm
+ var meta []byte
+ if params.Meta != nil {
+ meta, err = json.Marshal(params.Meta)
+ if err != nil {
+ ctx.ServerError("Marshal", err)
+ return
+ }
}
w := &webhook.Webhook{
RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- HTTPMethod: form.HTTPMethod,
- ContentType: contentType,
- Secret: form.Secret,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.GITEA,
+ URL: params.URL,
+ HTTPMethod: params.HTTPMethod,
+ ContentType: params.ContentType,
+ Secret: params.Secret,
+ HookEvent: ParseHookEvent(params.WebhookForm),
+ IsActive: params.WebhookForm.Active,
+ Type: params.Type,
+ Meta: string(meta),
OrgID: orCtx.OrgID,
IsSystemWebhook: orCtx.IsSystemWebhook,
}
@@ -235,503 +248,175 @@ func GiteaHooksNewPost(ctx *context.Context) {
ctx.Redirect(orCtx.Link)
}
-// GogsHooksNewPost response for creating webhook
-func GogsHooksNewPost(ctx *context.Context) {
- form := web.GetForm(ctx).(*forms.NewGogshookForm)
- newGogsWebhookPost(ctx, *form, webhook.GOGS)
-}
-
-// newGogsWebhookPost response for creating gogs hook
-func newGogsWebhookPost(ctx *context.Context, form forms.NewGogshookForm, kind webhook.HookType) {
- ctx.Data["Title"] = ctx.Tr("repo.settings.add_webhook")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.GOGS
+// GiteaHooksNewPost response for creating Gitea webhook
+func GiteaHooksNewPost(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.NewWebhookForm)
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
+ contentType := webhook.ContentTypeJSON
+ if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
+ contentType = webhook.ContentTypeForm
}
- ctx.Data["BaseLink"] = orCtx.LinkNew
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: contentType,
+ Secret: form.Secret,
+ HTTPMethod: form.HTTPMethod,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.GITEA,
+ })
+}
+
+// GogsHooksNewPost response for creating webhook
+func GogsHooksNewPost(ctx *context.Context) {
+ form := web.GetForm(ctx).(*forms.NewGogshookForm)
contentType := webhook.ContentTypeJSON
if webhook.HookContentType(form.ContentType) == webhook.ContentTypeForm {
contentType = webhook.ContentTypeForm
}
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: contentType,
- Secret: form.Secret,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: kind,
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: contentType,
+ Secret: form.Secret,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.GOGS,
+ })
}
// DiscordHooksNewPost response for creating discord hook
func DiscordHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewDiscordHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.DISCORD
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&webhook_service.DiscordMeta{
- Username: form.Username,
- IconURL: form.IconURL,
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.DISCORD,
+ Meta: &webhook_service.DiscordMeta{
+ Username: form.Username,
+ IconURL: form.IconURL,
+ },
})
- if err != nil {
- ctx.ServerError("Marshal", err)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.DISCORD,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
}
// DingtalkHooksNewPost response for creating dingtalk hook
func DingtalkHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewDingtalkHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.DINGTALK
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.DINGTALK,
- Meta: "",
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.DINGTALK,
+ })
}
// TelegramHooksNewPost response for creating telegram hook
func TelegramHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewTelegramHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.TELEGRAM
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
- meta, err := json.Marshal(&webhook_service.TelegramMeta{
- BotToken: form.BotToken,
- ChatID: form.ChatID,
+ createWebhook(ctx, webhookCreationParams{
+ URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)),
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.TELEGRAM,
+ Meta: &webhook_service.TelegramMeta{
+ BotToken: form.BotToken,
+ ChatID: form.ChatID,
+ },
})
- if err != nil {
- ctx.ServerError("Marshal", err)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: fmt.Sprintf("https://api.telegram.org/bot%s/sendMessage?chat_id=%s", url.PathEscape(form.BotToken), url.QueryEscape(form.ChatID)),
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.TELEGRAM,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
}
// MatrixHooksNewPost response for creating a Matrix hook
func MatrixHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewMatrixHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.MATRIX
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&webhook_service.MatrixMeta{
- HomeserverURL: form.HomeserverURL,
- Room: form.RoomID,
- AccessToken: form.AccessToken,
- MessageType: form.MessageType,
+ createWebhook(ctx, webhookCreationParams{
+ URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)),
+ ContentType: webhook.ContentTypeJSON,
+ HTTPMethod: http.MethodPut,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.MATRIX,
+ Meta: &webhook_service.MatrixMeta{
+ HomeserverURL: form.HomeserverURL,
+ Room: form.RoomID,
+ AccessToken: form.AccessToken,
+ MessageType: form.MessageType,
+ },
})
- if err != nil {
- ctx.ServerError("Marshal", err)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: fmt.Sprintf("%s/_matrix/client/r0/rooms/%s/send/m.room.message", form.HomeserverURL, url.PathEscape(form.RoomID)),
- ContentType: webhook.ContentTypeJSON,
- HTTPMethod: "PUT",
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.MATRIX,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
}
// MSTeamsHooksNewPost response for creating MS Teams hook
func MSTeamsHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewMSTeamsHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.MSTEAMS
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.MSTEAMS,
- Meta: "",
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.MSTEAMS,
+ })
}
// SlackHooksNewPost response for creating slack hook
func SlackHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewSlackHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.SLACK
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- if form.HasInvalidChannel() {
- ctx.Flash.Error(ctx.Tr("repo.settings.add_webhook.invalid_channel_name"))
- ctx.Redirect(orCtx.LinkNew + "/slack/new")
- return
- }
- meta, err := json.Marshal(&webhook_service.SlackMeta{
- Channel: strings.TrimSpace(form.Channel),
- Username: form.Username,
- IconURL: form.IconURL,
- Color: form.Color,
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.SLACK,
+ Meta: &webhook_service.SlackMeta{
+ Channel: strings.TrimSpace(form.Channel),
+ Username: form.Username,
+ IconURL: form.IconURL,
+ Color: form.Color,
+ },
})
- if err != nil {
- ctx.ServerError("Marshal", err)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.SLACK,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
}
// FeishuHooksNewPost response for creating feishu hook
func FeishuHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewFeishuHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.FEISHU
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.FEISHU,
- Meta: "",
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.FEISHU,
+ })
}
// WechatworkHooksNewPost response for creating wechatwork hook
func WechatworkHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewWechatWorkHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.WECHATWORK
-
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: form.PayloadURL,
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.WECHATWORK,
- Meta: "",
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
+ createWebhook(ctx, webhookCreationParams{
+ URL: form.PayloadURL,
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.WECHATWORK,
+ })
}
// PackagistHooksNewPost response for creating packagist hook
func PackagistHooksNewPost(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewPackagistHookForm)
- ctx.Data["Title"] = ctx.Tr("repo.settings")
- ctx.Data["PageIsSettingsHooks"] = true
- ctx.Data["PageIsSettingsHooksNew"] = true
- ctx.Data["Webhook"] = webhook.Webhook{HookEvent: &webhook.HookEvent{}}
- ctx.Data["HookType"] = webhook.PACKAGIST
- orCtx, err := getOrgRepoCtx(ctx)
- if err != nil {
- ctx.ServerError("getOrgRepoCtx", err)
- return
- }
-
- if ctx.HasError() {
- ctx.HTML(http.StatusOK, orCtx.NewTemplate)
- return
- }
-
- meta, err := json.Marshal(&webhook_service.PackagistMeta{
- Username: form.Username,
- APIToken: form.APIToken,
- PackageURL: form.PackageURL,
+ createWebhook(ctx, webhookCreationParams{
+ URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)),
+ ContentType: webhook.ContentTypeJSON,
+ WebhookForm: form.WebhookForm,
+ Type: webhook.PACKAGIST,
+ Meta: &webhook_service.PackagistMeta{
+ Username: form.Username,
+ APIToken: form.APIToken,
+ PackageURL: form.PackageURL,
+ },
})
- if err != nil {
- ctx.ServerError("Marshal", err)
- return
- }
-
- w := &webhook.Webhook{
- RepoID: orCtx.RepoID,
- URL: fmt.Sprintf("https://packagist.org/api/update-package?username=%s&apiToken=%s", url.QueryEscape(form.Username), url.QueryEscape(form.APIToken)),
- ContentType: webhook.ContentTypeJSON,
- HookEvent: ParseHookEvent(form.WebhookForm),
- IsActive: form.Active,
- Type: webhook.PACKAGIST,
- Meta: string(meta),
- OrgID: orCtx.OrgID,
- IsSystemWebhook: orCtx.IsSystemWebhook,
- }
- if err := w.UpdateEvent(); err != nil {
- ctx.ServerError("UpdateEvent", err)
- return
- } else if err := webhook.CreateWebhook(ctx, w); err != nil {
- ctx.ServerError("CreateWebhook", err)
- return
- }
-
- ctx.Flash.Success(ctx.Tr("repo.settings.add_hook_success"))
- ctx.Redirect(orCtx.Link)
}
func checkWebhook(ctx *context.Context) (*orgRepoCtx, *webhook.Webhook) {
@@ -894,12 +579,6 @@ func SlackHooksEditPost(ctx *context.Context) {
return
}
- if form.HasInvalidChannel() {
- ctx.Flash.Error(ctx.Tr("repo.settings.add_webhook.invalid_channel_name"))
- ctx.Redirect(fmt.Sprintf("%s/%d", orCtx.Link, w.ID))
- return
- }
-
meta, err := json.Marshal(&webhook_service.SlackMeta{
Channel: strings.TrimSpace(form.Channel),
Username: form.Username,
diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go
index e4134028aa9d..4cd5856ea647 100644
--- a/routers/web/repo/wiki.go
+++ b/routers/web/repo/wiki.go
@@ -239,9 +239,28 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
Metas: ctx.Repo.Repository.ComposeDocumentMetas(),
IsWiki: true,
}
-
- var buf strings.Builder
- if err := markdown.Render(rctx, bytes.NewReader(data), &buf); err != nil {
+ buf := &strings.Builder{}
+
+ renderFn := func(data []byte) (escaped *charset.EscapeStatus, output string, err error) {
+ markupRd, markupWr := io.Pipe()
+ defer markupWr.Close()
+ done := make(chan struct{})
+ go func() {
+ // We allow NBSP here this is rendered
+ escaped, _ = charset.EscapeControlReader(markupRd, buf, ctx.Locale, charset.RuneNBSP)
+ output = buf.String()
+ buf.Reset()
+ close(done)
+ }()
+
+ err = markdown.Render(rctx, bytes.NewReader(data), markupWr)
+ _ = markupWr.CloseWithError(err)
+ <-done
+ return escaped, output, err
+ }
+
+ ctx.Data["EscapeStatus"], ctx.Data["content"], err = renderFn(data)
+ if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
@@ -249,11 +268,10 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
- ctx.Data["EscapeStatus"], ctx.Data["content"] = charset.EscapeControlString(buf.String())
-
if !isSideBar {
buf.Reset()
- if err := markdown.Render(rctx, bytes.NewReader(sidebarContent), &buf); err != nil {
+ ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"], err = renderFn(sidebarContent)
+ if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
@@ -261,14 +279,14 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
ctx.Data["sidebarPresent"] = sidebarContent != nil
- ctx.Data["sidebarEscapeStatus"], ctx.Data["sidebarContent"] = charset.EscapeControlString(buf.String())
} else {
ctx.Data["sidebarPresent"] = false
}
if !isFooter {
buf.Reset()
- if err := markdown.Render(rctx, bytes.NewReader(footerContent), &buf); err != nil {
+ ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"], err = renderFn(footerContent)
+ if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
@@ -276,7 +294,6 @@ func renderViewPage(ctx *context.Context) (*git.Repository, *git.TreeEntry) {
return nil, nil
}
ctx.Data["footerPresent"] = footerContent != nil
- ctx.Data["footerEscapeStatus"], ctx.Data["footerContent"] = charset.EscapeControlString(buf.String())
} else {
ctx.Data["footerPresent"] = false
}
@@ -343,12 +360,12 @@ func renderRevisionPage(ctx *context.Context) (*git.Repository, *git.TreeEntry)
}
// get Commit Count
- commitsHistory, err := wikiRepo.CommitsByFileAndRangeNoFollow("master", pageFilename, page)
+ commitsHistory, err := wikiRepo.CommitsByFileAndRange("master", pageFilename, page)
if err != nil {
if wikiRepo != nil {
wikiRepo.Close()
}
- ctx.ServerError("CommitsByFileAndRangeNoFollow", err)
+ ctx.ServerError("CommitsByFileAndRange", err)
return nil, nil
}
ctx.Data["Commits"] = git_model.ConvertFromGitCommit(commitsHistory, ctx.Repo.Repository)
diff --git a/routers/web/user/home.go b/routers/web/user/home.go
index 648269980472..5e17239e348c 100644
--- a/routers/web/user/home.go
+++ b/routers/web/user/home.go
@@ -607,10 +607,8 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
var shownIssues int
if !isShowClosed {
shownIssues = int(issueStats.OpenCount)
- ctx.Data["TotalIssueCount"] = shownIssues
} else {
shownIssues = int(issueStats.ClosedCount)
- ctx.Data["TotalIssueCount"] = shownIssues
}
if len(repoIDs) != 0 {
shownIssues = 0
@@ -619,6 +617,19 @@ func buildIssueOverview(ctx *context.Context, unitType unit.Type) {
}
}
+ var allIssueCount int64
+ for _, issueCount := range issueCountByRepo {
+ allIssueCount += issueCount
+ }
+ ctx.Data["TotalIssueCount"] = allIssueCount
+
+ if len(repoIDs) == 1 {
+ repo := showReposMap[repoIDs[0]]
+ if repo != nil {
+ ctx.Data["SingleRepoLink"] = repo.Link()
+ }
+ }
+
ctx.Data["IsShowClosed"] = isShowClosed
ctx.Data["IssueRefEndNames"], ctx.Data["IssueRefURLs"] = issue_service.GetRefEndNamesAndURLs(issues, ctx.FormString("RepoLink"))
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 6f23d239e26a..c804be3c5f74 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -105,6 +105,13 @@ func Profile(ctx *context.Context) {
ctx.Data["Orgs"] = orgs
ctx.Data["HasOrgsVisible"] = organization.HasOrgsVisible(orgs, ctx.Doer)
+ badges, _, err := user_model.GetUserBadges(ctx, ctx.ContextUser)
+ if err != nil {
+ ctx.ServerError("GetUserBadges", err)
+ return
+ }
+ ctx.Data["Badges"] = badges
+
tab := ctx.FormString("tab")
ctx.Data["TabName"] = tab
diff --git a/routers/web/web.go b/routers/web/web.go
index a9f43fb2c4fe..34d3de6fde0a 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -22,7 +22,6 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
"code.gitea.io/gitea/modules/structs"
- "code.gitea.io/gitea/modules/templates"
"code.gitea.io/gitea/modules/validation"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/modules/web/routing"
@@ -43,7 +42,6 @@ import (
context_service "code.gitea.io/gitea/services/context"
"code.gitea.io/gitea/services/forms"
"code.gitea.io/gitea/services/lfs"
- "code.gitea.io/gitea/services/mailer"
_ "code.gitea.io/gitea/modules/session" // to registers all internal adapters
@@ -152,8 +150,6 @@ func Routes() *web.Route {
common = append(common, h)
}
- mailer.InitMailRender(templates.Mailer())
-
if setting.Service.EnableCaptcha {
// The captcha http.Handler should only fire on /captcha/* so we can just mount this on that url
routes.Route("/captcha/*", "GET,HEAD", append(common, captcha.Captchaer(context.GetImageCaptcha()))...)
diff --git a/services/asymkey/ssh_key_test.go b/services/asymkey/ssh_key_test.go
index 182371271a4c..9bc23a719c68 100644
--- a/services/asymkey/ssh_key_test.go
+++ b/services/asymkey/ssh_key_test.go
@@ -18,7 +18,7 @@ import (
func TestAddLdapSSHPublicKeys(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
s := &auth.Source{ID: 1}
testCases := []struct {
diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go
index 889151d8f350..561792db2f20 100644
--- a/services/attachment/attachment_test.go
+++ b/services/attachment/attachment_test.go
@@ -26,7 +26,7 @@ func TestMain(m *testing.M) {
func TestUploadAttachment(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
fPath := "./attachment_test.go"
f, err := os.Open(fPath)
diff --git a/services/auth/reverseproxy.go b/services/auth/reverseproxy.go
index 05d6af78f174..d9d1b63e8fea 100644
--- a/services/auth/reverseproxy.go
+++ b/services/auth/reverseproxy.go
@@ -105,9 +105,15 @@ func (r *ReverseProxy) newUser(req *http.Request) *user_model.User {
}
}
+ var fullname string
+ if setting.Service.EnableReverseProxyFullName {
+ fullname = req.Header.Get(setting.ReverseProxyAuthFullName)
+ }
+
user := &user_model.User{
- Name: username,
- Email: email,
+ Name: username,
+ Email: email,
+ FullName: fullname,
}
overwriteDefault := user_model.CreateUserOverwriteOptions{
diff --git a/services/auth/source/oauth2/jwtsigningkey.go b/services/auth/source/oauth2/jwtsigningkey.go
index 24f2c41119c1..d6b3c05a4fcb 100644
--- a/services/auth/source/oauth2/jwtsigningkey.go
+++ b/services/auth/source/oauth2/jwtsigningkey.go
@@ -31,11 +31,11 @@ import (
// ErrInvalidAlgorithmType represents an invalid algorithm error.
type ErrInvalidAlgorithmType struct {
- Algorightm string
+ Algorithm string
}
func (err ErrInvalidAlgorithmType) Error() string {
- return fmt.Sprintf("JWT signing algorithm is not supported: %s", err.Algorightm)
+ return fmt.Sprintf("JWT signing algorithm is not supported: %s", err.Algorithm)
}
// JWTSigningKey represents a algorithm/key pair to sign JWTs
diff --git a/services/forms/repo_form.go b/services/forms/repo_form.go
index afecc205f31e..7a4a2123ebd2 100644
--- a/services/forms/repo_form.go
+++ b/services/forms/repo_form.go
@@ -17,7 +17,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/web/middleware"
- "code.gitea.io/gitea/routers/utils"
+ "code.gitea.io/gitea/services/webhook"
"gitea.com/go-chi/binding"
)
@@ -305,14 +305,16 @@ type NewSlackHookForm struct {
// Validate validates the fields
func (f *NewSlackHookForm) Validate(req *http.Request, errs binding.Errors) binding.Errors {
ctx := context.GetContext(req)
+ if !webhook.IsValidSlackChannel(strings.TrimSpace(f.Channel)) {
+ errs = append(errs, binding.Error{
+ FieldNames: []string{"Channel"},
+ Classification: "",
+ Message: ctx.Tr("repo.settings.add_webhook.invalid_channel_name"),
+ })
+ }
return middleware.Validate(errs, ctx.Data, f, ctx.Locale)
}
-// HasInvalidChannel validates the channel name is in the right format
-func (f NewSlackHookForm) HasInvalidChannel() bool {
- return !utils.IsValidSlackChannel(f.Channel)
-}
-
// NewDiscordHookForm form for creating discord hook
type NewDiscordHookForm struct {
PayloadURL string `binding:"Required;ValidUrl"`
diff --git a/services/forms/user_form.go b/services/forms/user_form.go
index c8f2b02d8c80..8ce1d85c5778 100644
--- a/services/forms/user_form.go
+++ b/services/forms/user_form.go
@@ -96,6 +96,7 @@ type RegisterForm struct {
Retype string
GRecaptchaResponse string `form:"g-recaptcha-response"`
HcaptchaResponse string `form:"h-captcha-response"`
+ McaptchaResponse string `form:"m-captcha-response"`
}
// Validate validates the fields
diff --git a/services/forms/user_form_auth_openid.go b/services/forms/user_form_auth_openid.go
index fd3368d303a9..992517f34f0f 100644
--- a/services/forms/user_form_auth_openid.go
+++ b/services/forms/user_form_auth_openid.go
@@ -31,6 +31,7 @@ type SignUpOpenIDForm struct {
Email string `binding:"Required;Email;MaxSize(254)"`
GRecaptchaResponse string `form:"g-recaptcha-response"`
HcaptchaResponse string `form:"h-captcha-response"`
+ McaptchaResponse string `form:"m-captcha-response"`
}
// Validate validates the fields
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 6dd237bbc8d4..9844992f5b11 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -32,6 +32,7 @@ import (
"code.gitea.io/gitea/modules/lfs"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/translation"
"github.com/sergi/go-diff/diffmatchpatch"
stdcharset "golang.org/x/net/html/charset"
@@ -169,11 +170,11 @@ func getDiffLineSectionInfo(treePath, line string, lastLeftIdx, lastRightIdx int
}
// escape a line's content or return needed for copy/paste purposes
-func getLineContent(content string) DiffInline {
+func getLineContent(content string, locale translation.Locale) DiffInline {
if len(content) > 0 {
- return DiffInlineWithUnicodeEscape(template.HTML(html.EscapeString(content)))
+ return DiffInlineWithUnicodeEscape(template.HTML(html.EscapeString(content)), locale)
}
- return DiffInline{Content: " "}
+ return DiffInline{EscapeStatus: &charset.EscapeStatus{}, Content: " "}
}
// DiffSection represents a section of a DiffFile.
@@ -267,26 +268,26 @@ func init() {
// DiffInline is a struct that has a content and escape status
type DiffInline struct {
- EscapeStatus charset.EscapeStatus
+ EscapeStatus *charset.EscapeStatus
Content template.HTML
}
// DiffInlineWithUnicodeEscape makes a DiffInline with hidden unicode characters escaped
-func DiffInlineWithUnicodeEscape(s template.HTML) DiffInline {
- status, content := charset.EscapeControlString(string(s))
+func DiffInlineWithUnicodeEscape(s template.HTML, locale translation.Locale) DiffInline {
+ status, content := charset.EscapeControlHTML(string(s), locale)
return DiffInline{EscapeStatus: status, Content: template.HTML(content)}
}
// DiffInlineWithHighlightCode makes a DiffInline with code highlight and hidden unicode characters escaped
-func DiffInlineWithHighlightCode(fileName, language, code string) DiffInline {
- status, content := charset.EscapeControlString(highlight.Code(fileName, language, code))
+func DiffInlineWithHighlightCode(fileName, language, code string, locale translation.Locale) DiffInline {
+ status, content := charset.EscapeControlHTML(highlight.Code(fileName, language, code), locale)
return DiffInline{EscapeStatus: status, Content: template.HTML(content)}
}
// GetComputedInlineDiffFor computes inline diff for the given line.
-func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) DiffInline {
+func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine, locale translation.Locale) DiffInline {
if setting.Git.DisableDiffHighlight {
- return getLineContent(diffLine.Content[1:])
+ return getLineContent(diffLine.Content[1:], locale)
}
var (
@@ -303,26 +304,26 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) Dif
// try to find equivalent diff line. ignore, otherwise
switch diffLine.Type {
case DiffLineSection:
- return getLineContent(diffLine.Content[1:])
+ return getLineContent(diffLine.Content[1:], locale)
case DiffLineAdd:
compareDiffLine = diffSection.GetLine(DiffLineDel, diffLine.RightIdx)
if compareDiffLine == nil {
- return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:])
+ return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale)
}
diff1 = compareDiffLine.Content
diff2 = diffLine.Content
case DiffLineDel:
compareDiffLine = diffSection.GetLine(DiffLineAdd, diffLine.LeftIdx)
if compareDiffLine == nil {
- return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:])
+ return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale)
}
diff1 = diffLine.Content
diff2 = compareDiffLine.Content
default:
if strings.IndexByte(" +-", diffLine.Content[0]) > -1 {
- return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:])
+ return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content[1:], locale)
}
- return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content)
+ return DiffInlineWithHighlightCode(diffSection.FileName, language, diffLine.Content, locale)
}
hcd := newHighlightCodeDiff()
@@ -330,7 +331,7 @@ func (diffSection *DiffSection) GetComputedInlineDiffFor(diffLine *DiffLine) Dif
// it seems that Gitea doesn't need the line wrapper of Chroma, so do not add them back
// if the line wrappers are still needed in the future, it can be added back by "diffToHTML(hcd.lineWrapperTags. ...)"
diffHTML := diffToHTML(nil, diffRecord, diffLine.Type)
- return DiffInlineWithUnicodeEscape(template.HTML(diffHTML))
+ return DiffInlineWithUnicodeEscape(template.HTML(diffHTML), locale)
}
// DiffFile represents a file diff.
diff --git a/services/gitdiff/gitdiff_test.go b/services/gitdiff/gitdiff_test.go
index e88d831759b7..dfdd4df9c445 100644
--- a/services/gitdiff/gitdiff_test.go
+++ b/services/gitdiff/gitdiff_test.go
@@ -601,8 +601,8 @@ func setupDefaultDiff() *Diff {
func TestDiff_LoadComments(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}).(*issues_model.Issue)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
diff := setupDefaultDiff()
assert.NoError(t, diff.LoadComments(db.DefaultContext, issue, user))
assert.Len(t, diff.Files[0].Sections[0].Lines[0].Comments, 2)
diff --git a/services/issue/commit_test.go b/services/issue/commit_test.go
index ce3f91362717..f9ad0302ffd6 100644
--- a/services/issue/commit_test.go
+++ b/services/issue/commit_test.go
@@ -47,8 +47,8 @@ func TestUpdateIssuesCommit(t *testing.T) {
},
}
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo.Owner = user
commentBean := &issues_model.Comment{
@@ -77,7 +77,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
Message: "close #1",
},
}
- repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
commentBean = &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
@@ -103,7 +103,7 @@ func TestUpdateIssuesCommit(t *testing.T) {
Message: "close " + setting.AppURL + repo.FullName() + "/pulls/1",
},
}
- repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
commentBean = &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef3",
@@ -133,8 +133,8 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
},
}
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repo.Owner = user
issueBean := &issues_model.Issue{RepoID: repo.ID, Index: 4}
@@ -147,7 +147,7 @@ func TestUpdateIssuesCommit_Colon(t *testing.T) {
func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that push to a non-default branch closes an issue.
pushCommits := []*repository.PushCommit{
@@ -161,7 +161,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
},
}
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
@@ -181,7 +181,7 @@ func TestUpdateIssuesCommit_Issue5957(t *testing.T) {
func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
@@ -196,7 +196,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
},
}
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
@@ -216,7 +216,7 @@ func TestUpdateIssuesCommit_AnotherRepo(t *testing.T) {
func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
// Test that a push to default branch closes issue in another repo
// If the user also has push permissions to that repo
@@ -231,7 +231,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
},
}
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef1",
@@ -251,7 +251,7 @@ func TestUpdateIssuesCommit_AnotherRepo_FullAddress(t *testing.T) {
func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10})
// Test that a push with close reference *can not* close issue
// If the committer doesn't have push rights in that repo
@@ -274,7 +274,7 @@ func TestUpdateIssuesCommit_AnotherRepoNoPermission(t *testing.T) {
},
}
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 6})
commentBean := &issues_model.Comment{
Type: issues_model.CommentTypeCommitRef,
CommitSHA: "abcdef3",
diff --git a/services/issue/label_test.go b/services/issue/label_test.go
index 120c9ea4f131..482db95139b0 100644
--- a/services/issue/label_test.go
+++ b/services/issue/label_test.go
@@ -27,12 +27,12 @@ func TestIssue_AddLabels(t *testing.T) {
}
for _, test := range tests {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
labels := make([]*issues_model.Label, len(test.labelIDs))
for i, labelID := range test.labelIDs {
- labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}).(*issues_model.Label)
+ labels[i] = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID})
}
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
assert.NoError(t, AddLabels(issue, doer, labels))
for _, labelID := range test.labelIDs {
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: labelID})
@@ -53,9 +53,9 @@ func TestIssue_AddLabel(t *testing.T) {
}
for _, test := range tests {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID}).(*issues_model.Issue)
- label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID}).(*issues_model.Label)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: test.issueID})
+ label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: test.labelID})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: test.doerID})
assert.NoError(t, AddLabel(issue, doer, label))
unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: test.issueID, LabelID: test.labelID})
}
diff --git a/services/issue/milestone_test.go b/services/issue/milestone_test.go
index d08b1ae8c7fe..087c25670004 100644
--- a/services/issue/milestone_test.go
+++ b/services/issue/milestone_test.go
@@ -16,8 +16,8 @@ import (
func TestChangeMilestoneAssign(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1}).(*issues_model.Issue)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ issue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{RepoID: 1})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NotNil(t, issue)
assert.NotNil(t, doer)
diff --git a/services/mailer/mail.go b/services/mailer/mail.go
index b8d79bd818a0..738a207ce8d0 100644
--- a/services/mailer/mail.go
+++ b/services/mailer/mail.go
@@ -55,12 +55,6 @@ var (
subjectRemoveSpaces = regexp.MustCompile(`[\s]+`)
)
-// InitMailRender initializes the mail renderer
-func InitMailRender(subjectTpl *texttmpl.Template, bodyTpl *template.Template) {
- subjectTemplates = subjectTpl
- bodyTemplates = bodyTpl
-}
-
// SendTestMail sends a test mail
func SendTestMail(email string) error {
if setting.MailService == nil {
diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go
index 93837ba8c4ca..4302b2c74b6e 100644
--- a/services/mailer/mail_test.go
+++ b/services/mailer/mail_test.go
@@ -56,20 +56,19 @@ func prepareMailerTest(t *testing.T) (doer *user_model.User, repo *repo_model.Re
setting.MailService = &mailService
setting.Domain = "localhost"
- doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer}).(*repo_model.Repository)
- issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer}).(*issues_model.Issue)
+ doer = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1, Owner: doer})
+ issue = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1, Repo: repo, Poster: doer})
assert.NoError(t, issue.LoadRepo(db.DefaultContext))
- comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue}).(*issues_model.Comment)
+ comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 2, Issue: issue})
return doer, repo, issue, comment
}
func TestComposeIssueCommentMessage(t *testing.T) {
doer, _, issue, comment := prepareMailerTest(t)
- stpl := texttmpl.Must(texttmpl.New("issue/comment").Parse(subjectTpl))
- btpl := template.Must(template.New("issue/comment").Parse(bodyTpl))
- InitMailRender(stpl, btpl)
+ subjectTemplates = texttmpl.Must(texttmpl.New("issue/comment").Parse(subjectTpl))
+ bodyTemplates = template.Must(template.New("issue/comment").Parse(bodyTpl))
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}}
msgs, err := composeIssueCommentMessages(&mailCommentContext{
@@ -97,9 +96,8 @@ func TestComposeIssueCommentMessage(t *testing.T) {
func TestComposeIssueMessage(t *testing.T) {
doer, _, issue, _ := prepareMailerTest(t)
- stpl := texttmpl.Must(texttmpl.New("issue/new").Parse(subjectTpl))
- btpl := template.Must(template.New("issue/new").Parse(bodyTpl))
- InitMailRender(stpl, btpl)
+ subjectTemplates = texttmpl.Must(texttmpl.New("issue/new").Parse(subjectTpl))
+ bodyTemplates = template.Must(template.New("issue/new").Parse(bodyTpl))
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}, {Name: "Test2", Email: "test2@gitea.com"}}
msgs, err := composeIssueCommentMessages(&mailCommentContext{
@@ -128,17 +126,15 @@ func TestTemplateSelection(t *testing.T) {
doer, repo, issue, comment := prepareMailerTest(t)
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}}
- stpl := texttmpl.Must(texttmpl.New("issue/default").Parse("issue/default/subject"))
- texttmpl.Must(stpl.New("issue/new").Parse("issue/new/subject"))
- texttmpl.Must(stpl.New("pull/comment").Parse("pull/comment/subject"))
- texttmpl.Must(stpl.New("issue/close").Parse("")) // Must default to fallback subject
+ subjectTemplates = texttmpl.Must(texttmpl.New("issue/default").Parse("issue/default/subject"))
+ texttmpl.Must(subjectTemplates.New("issue/new").Parse("issue/new/subject"))
+ texttmpl.Must(subjectTemplates.New("pull/comment").Parse("pull/comment/subject"))
+ texttmpl.Must(subjectTemplates.New("issue/close").Parse("")) // Must default to fallback subject
- btpl := template.Must(template.New("issue/default").Parse("issue/default/body"))
- template.Must(btpl.New("issue/new").Parse("issue/new/body"))
- template.Must(btpl.New("pull/comment").Parse("pull/comment/body"))
- template.Must(btpl.New("issue/close").Parse("issue/close/body"))
-
- InitMailRender(stpl, btpl)
+ bodyTemplates = template.Must(template.New("issue/default").Parse("issue/default/body"))
+ template.Must(bodyTemplates.New("issue/new").Parse("issue/new/body"))
+ template.Must(bodyTemplates.New("pull/comment").Parse("pull/comment/body"))
+ template.Must(bodyTemplates.New("issue/close").Parse("issue/close/body"))
expect := func(t *testing.T, msg *Message, expSubject, expBody string) {
subject := msg.ToMessage().GetHeader("Subject")
@@ -163,8 +159,8 @@ func TestTemplateSelection(t *testing.T) {
}, recipients, false, "TestTemplateSelection")
expect(t, msg, "issue/default/subject", "issue/default/body")
- pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer}).(*issues_model.Issue)
- comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull}).(*issues_model.Comment)
+ pull := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2, Repo: repo, Poster: doer})
+ comment = unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 4, Issue: pull})
msg = testComposeIssueCommentMessage(t, &mailCommentContext{
Context: context.TODO(), // TODO: use a correct context
Issue: pull, Doer: doer, ActionType: models.ActionCommentPull,
@@ -187,9 +183,8 @@ func TestTemplateServices(t *testing.T) {
expect := func(t *testing.T, issue *issues_model.Issue, comment *issues_model.Comment, doer *user_model.User,
actionType models.ActionType, fromMention bool, tplSubject, tplBody, expSubject, expBody string,
) {
- stpl := texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject))
- btpl := template.Must(template.New("issue/default").Parse(tplBody))
- InitMailRender(stpl, btpl)
+ subjectTemplates = texttmpl.Must(texttmpl.New("issue/default").Parse(tplSubject))
+ bodyTemplates = template.Must(template.New("issue/default").Parse(tplBody))
recipients := []*user_model.User{{Name: "Test", Email: "test@gitea.com"}}
msg := testComposeIssueCommentMessage(t, &mailCommentContext{
diff --git a/services/mailer/mailer.go b/services/mailer/mailer.go
index c86c54c748c5..fdbb6e562bfc 100644
--- a/services/mailer/mailer.go
+++ b/services/mailer/mailer.go
@@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/modules/process"
"code.gitea.io/gitea/modules/queue"
"code.gitea.io/gitea/modules/setting"
+ "code.gitea.io/gitea/modules/templates"
"github.com/jaytaylor/html2text"
"gopkg.in/gomail.v2"
@@ -379,6 +380,8 @@ func NewContext() {
}, &Message{})
go graceful.GetManager().RunWithShutdownFns(mailQueue.Run)
+
+ subjectTemplates, bodyTemplates = templates.Mailer()
}
// SendAsync send mail asynchronously
diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go
index 6ea1c20592b2..9fb3d6ffd6fc 100644
--- a/services/migrations/gitea_uploader_test.go
+++ b/services/migrations/gitea_uploader_test.go
@@ -37,7 +37,7 @@ func TestGiteaUploadRepo(t *testing.T) {
unittest.PrepareTestEnv(t)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
var (
ctx = context.Background()
@@ -63,7 +63,7 @@ func TestGiteaUploadRepo(t *testing.T) {
}, nil)
assert.NoError(t, err)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, Name: repoName})
assert.True(t, repo.HasWiki())
assert.EqualValues(t, repo_model.RepositoryReady, repo.Status)
@@ -127,8 +127,8 @@ func TestGiteaUploadRepo(t *testing.T) {
func TestGiteaUploadRemapLocalUser(t *testing.T) {
unittest.PrepareTestEnv(t)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
repoName := "migrated"
uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
@@ -177,7 +177,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) {
func TestGiteaUploadRemapExternalUser(t *testing.T) {
unittest.PrepareTestEnv(t)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
repoName := "migrated"
uploader := NewGiteaLocalUploader(context.Background(), doer, doer.Name, repoName)
@@ -205,7 +205,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) {
//
// Link the external ID to an existing user
//
- linkedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ linkedUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
externalLoginUser := &user_model.ExternalLoginUser{
ExternalID: strconv.FormatInt(externalID, 10),
UserID: linkedUser.ID,
@@ -232,7 +232,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
//
// fromRepo master
//
- fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ fromRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
baseRef := "master"
assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false))
err := git.NewCommand(git.DefaultContext, "symbolic-ref", "HEAD", git.BranchPrefix+baseRef).Run(&git.RunOpts{Dir: fromRepo.RepoPath()})
@@ -273,13 +273,13 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) {
headSHA, err := fromGitRepo.GetBranchCommitID(headRef)
assert.NoError(t, err)
- fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID}).(*user_model.User)
+ fromRepoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: fromRepo.OwnerID})
//
// forkRepo branch2
//
forkHeadRef := "branch2"
- forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8}).(*repo_model.Repository)
+ forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 8})
assert.NoError(t, git.CloneWithArgs(git.DefaultContext, fromRepo.RepoPath(), forkRepo.RepoPath(), []string{}, git.CloneRepoOptions{
Branch: headRef,
}))
diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go
index f2542173a0ee..9460c66dbce9 100644
--- a/services/migrations/migrate.go
+++ b/services/migrations/migrate.go
@@ -479,5 +479,10 @@ func Init() error {
}
// TODO: at the moment, if ALLOW_LOCALNETWORKS=false, ALLOWED_DOMAINS=domain.com, and domain.com has IP 127.0.0.1, then it's still allowed.
// if we want to block such case, the private&loopback should be added to the blockList when ALLOW_LOCALNETWORKS=false
+
+ if setting.Proxy.Enabled && setting.Proxy.ProxyURLFixed != nil {
+ allowList.AppendPattern(setting.Proxy.ProxyURLFixed.Host)
+ }
+
return nil
}
diff --git a/services/migrations/migrate_test.go b/services/migrations/migrate_test.go
index 53cfe6d3ebe8..3fc4034777e4 100644
--- a/services/migrations/migrate_test.go
+++ b/services/migrations/migrate_test.go
@@ -19,8 +19,8 @@ import (
func TestMigrateWhiteBlocklist(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}).(*user_model.User)
- nonAdminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"}).(*user_model.User)
+ adminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
+ nonAdminUser := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user2"})
setting.Migrations.AllowedDomains = "github.com"
setting.Migrations.AllowLocalNetworks = false
diff --git a/services/org/org_test.go b/services/org/org_test.go
index 7f90d85807a7..c4e6088a7132 100644
--- a/services/org/org_test.go
+++ b/services/org/org_test.go
@@ -24,18 +24,18 @@ func TestMain(m *testing.M) {
func TestDeleteOrganization(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6}).(*organization.Organization)
+ org := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 6})
assert.NoError(t, DeleteOrganization(org))
unittest.AssertNotExistsBean(t, &organization.Organization{ID: 6})
unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: 6})
unittest.AssertNotExistsBean(t, &organization.Team{OrgID: 6})
- org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}).(*organization.Organization)
+ org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3})
err := DeleteOrganization(org)
assert.Error(t, err)
assert.True(t, models.IsErrUserOwnRepos(err))
- user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5}).(*organization.Organization)
+ user := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 5})
assert.Error(t, DeleteOrganization(user))
unittest.CheckConsistencyFor(t, &user_model.User{}, &organization.Team{})
}
diff --git a/services/packages/packages.go b/services/packages/packages.go
index 975c5ddd3589..4bc31a34e805 100644
--- a/services/packages/packages.go
+++ b/services/packages/packages.go
@@ -450,7 +450,7 @@ func GetFileStreamByPackageVersionAndFileID(ctx context.Context, owner *user_mod
// GetFileStreamByPackageVersion returns the content of the specific package file
func GetFileStreamByPackageVersion(ctx context.Context, pv *packages_model.PackageVersion, pfi *PackageFileInfo) (io.ReadCloser, *packages_model.PackageFile, error) {
- pf, err := packages_model.GetFileForVersionByName(db.DefaultContext, pv.ID, pfi.Filename, pfi.CompositeKey)
+ pf, err := packages_model.GetFileForVersionByName(ctx, pv.ID, pfi.Filename, pfi.CompositeKey)
if err != nil {
return nil, nil, err
}
diff --git a/services/pull/check_test.go b/services/pull/check_test.go
index 21fe675bbcd5..b4de02b5e231 100644
--- a/services/pull/check_test.go
+++ b/services/pull/check_test.go
@@ -43,11 +43,11 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) {
prPatchCheckerQueue = q.(queue.UniqueQueue)
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
AddToTaskQueue(pr)
assert.Eventually(t, func() bool {
- pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
return pr.Status == issues_model.PullRequestStatusChecking
}, 1*time.Second, 100*time.Millisecond)
@@ -72,7 +72,7 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) {
assert.False(t, has)
assert.NoError(t, err)
- pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr = unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.Equal(t, issues_model.PullRequestStatusChecking, pr.Status)
for _, callback := range queueShutdown {
diff --git a/services/pull/pull_test.go b/services/pull/pull_test.go
index 9160c434600c..769e3c72e9d2 100644
--- a/services/pull/pull_test.go
+++ b/services/pull/pull_test.go
@@ -38,7 +38,7 @@ func TestPullRequest_CommitMessageTrailersPattern(t *testing.T) {
func TestPullRequest_GetDefaultMergeMessage_InternalTracker(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2})
assert.NoError(t, pr.LoadBaseRepo())
gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath())
@@ -65,10 +65,10 @@ func TestPullRequest_GetDefaultMergeMessage_ExternalTracker(t *testing.T) {
ExternalTrackerFormat: "https://someurl.com/{user}/{repo}/{issue}",
},
}
- baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
baseRepo.Units = []*repo_model.RepoUnit{&externalTracker}
- pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo}).(*issues_model.PullRequest)
+ pr := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: 2, BaseRepo: baseRepo})
assert.NoError(t, pr.LoadBaseRepo())
gitRepo, err := git.OpenRepository(git.DefaultContext, pr.BaseRepo.RepoPath())
diff --git a/services/release/release_test.go b/services/release/release_test.go
index 0f5b74f70d57..d1a9298b6995 100644
--- a/services/release/release_test.go
+++ b/services/release/release_test.go
@@ -30,8 +30,8 @@ func TestMain(m *testing.M) {
func TestRelease_Create(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath)
@@ -134,8 +134,8 @@ func TestRelease_Create(t *testing.T) {
func TestRelease_Update(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath)
@@ -276,8 +276,8 @@ func TestRelease_Update(t *testing.T) {
func TestRelease_createTag(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
repoPath := repo_model.RepoPath(user.Name, repo.Name)
gitRepo, err := git.OpenRepository(git.DefaultContext, repoPath)
@@ -358,8 +358,8 @@ func TestRelease_createTag(t *testing.T) {
func TestCreateNewTag(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.NoError(t, CreateNewTag(git.DefaultContext, user, repo, "master", "v2.0",
"v2.0 is released \n\n BUGFIX: .... \n\n 123"))
diff --git a/services/repository/avatar.go b/services/repository/avatar.go
index dcf04c7e547c..b9bd36ab6658 100644
--- a/services/repository/avatar.go
+++ b/services/repository/avatar.go
@@ -96,7 +96,7 @@ func DeleteAvatar(repo *repo_model.Repository) error {
// RemoveRandomAvatars removes the randomly generated avatars that were created for repositories
func RemoveRandomAvatars(ctx context.Context) error {
- return repo_model.IterateRepository(func(repository *repo_model.Repository) error {
+ return db.IterateObjects(ctx, func(repository *repo_model.Repository) error {
select {
case <-ctx.Done():
return db.ErrCancelledf("before random avatars removed for %s", repository.FullName())
diff --git a/services/repository/avatar_test.go b/services/repository/avatar_test.go
index efad392a2dbc..e5d9ac9d53e5 100644
--- a/services/repository/avatar_test.go
+++ b/services/repository/avatar_test.go
@@ -25,7 +25,7 @@ func TestUploadAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(repo, buff.Bytes())
assert.NoError(t, err)
@@ -39,7 +39,7 @@ func TestUploadBigAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(repo, buff.Bytes())
assert.Error(t, err)
@@ -52,7 +52,7 @@ func TestDeleteAvatar(t *testing.T) {
png.Encode(&buff, myImage)
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
err := UploadAvatar(repo, buff.Bytes())
assert.NoError(t, err)
diff --git a/services/repository/fork_test.go b/services/repository/fork_test.go
index 965887b5d14b..376c5c06d944 100644
--- a/services/repository/fork_test.go
+++ b/services/repository/fork_test.go
@@ -20,8 +20,8 @@ func TestForkRepository(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// user 13 has already forked repo10
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10}).(*repo_model.Repository)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 13})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 10})
fork, err := ForkRepository(git.DefaultContext, user, user, ForkRepoOptions{
BaseRepo: repo,
diff --git a/services/repository/review_test.go b/services/repository/review_test.go
index 640657d1dd22..badacf39a6f1 100644
--- a/services/repository/review_test.go
+++ b/services/repository/review_test.go
@@ -16,12 +16,12 @@ import (
func TestRepoGetReviewerTeams(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
teams, err := GetReviewerTeams(repo2)
assert.NoError(t, err)
assert.Empty(t, teams)
- repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ repo3 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
teams, err = GetReviewerTeams(repo3)
assert.NoError(t, err)
assert.Len(t, teams, 2)
diff --git a/services/repository/template.go b/services/repository/template.go
index d7e8145811fe..b73abdce587f 100644
--- a/services/repository/template.go
+++ b/services/repository/template.go
@@ -7,12 +7,10 @@ package repository
import (
"context"
- "code.gitea.io/gitea/models"
"code.gitea.io/gitea/models/db"
issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
- "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/notification"
repo_module "code.gitea.io/gitea/modules/repository"
)
@@ -23,6 +21,11 @@ func GenerateIssueLabels(ctx context.Context, templateRepo, generateRepo *repo_m
if err != nil {
return err
}
+ // Prevent insert being called with an empty slice which would result in
+ // err "no element on slice when insert".
+ if len(templateLabels) == 0 {
+ return nil
+ }
newLabels := make([]*issues_model.Label, 0, len(templateLabels))
for _, templateLabel := range templateLabels {
@@ -95,11 +98,6 @@ func GenerateRepository(doer, owner *user_model.User, templateRepo *repo_model.R
return nil
}); err != nil {
- if generateRepo != nil && generateRepo.ID > 0 {
- if errDelete := models.DeleteRepository(doer, owner.ID, generateRepo.ID); errDelete != nil {
- log.Error("Rollback deleteRepository: %v", errDelete)
- }
- }
return nil, err
}
diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go
index 8be8c5353ddf..3c929f2f7bed 100644
--- a/services/repository/transfer_test.go
+++ b/services/repository/transfer_test.go
@@ -35,12 +35,12 @@ func TestTransferOwnership(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
- repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
+ repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
assert.NoError(t, TransferOwnership(doer, doer, repo, nil))
- transferredRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
+ transferredRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
assert.EqualValues(t, 2, transferredRepo.OwnerID)
exist, err := util.IsExist(repo_model.RepoPath("user3", "repo3"))
@@ -62,10 +62,10 @@ func TestTransferOwnership(t *testing.T) {
func TestStartRepositoryTransferSetPermission(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
- recipient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5}).(*user_model.User)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3}).(*repo_model.Repository)
- repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}).(*user_model.User)
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
+ recipient := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 5})
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 3})
+ repo.Owner = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
hasAccess, err := access_model.HasAccess(db.DefaultContext, recipient.ID, repo)
assert.NoError(t, err)
diff --git a/services/user/user_test.go b/services/user/user_test.go
index d8673593df22..c07244e7e1e7 100644
--- a/services/user/user_test.go
+++ b/services/user/user_test.go
@@ -28,7 +28,7 @@ func TestMain(m *testing.M) {
func TestDeleteUser(t *testing.T) {
test := func(userID int64) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
ownedRepos := make([]*repo_model.Repository, 0, 10)
assert.NoError(t, db.GetEngine(db.DefaultContext).Find(&ownedRepos, &repo_model.Repository{OwnerID: userID}))
@@ -56,14 +56,14 @@ func TestDeleteUser(t *testing.T) {
test(8)
test(11)
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
assert.Error(t, DeleteUser(db.DefaultContext, org, false))
}
func TestPurgeUser(t *testing.T) {
test := func(userID int64) {
assert.NoError(t, unittest.PrepareTestDatabase())
- user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID}).(*user_model.User)
+ user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: userID})
err := DeleteUser(db.DefaultContext, user, true)
assert.NoError(t, err)
@@ -76,7 +76,7 @@ func TestPurgeUser(t *testing.T) {
test(8)
test(11)
- org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3}).(*user_model.User)
+ org := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 3})
assert.Error(t, DeleteUser(db.DefaultContext, org, false))
}
diff --git a/services/webhook/slack.go b/services/webhook/slack.go
index 11e1d3c081c2..e3d0d406de3f 100644
--- a/services/webhook/slack.go
+++ b/services/webhook/slack.go
@@ -7,6 +7,7 @@ package webhook
import (
"errors"
"fmt"
+ "regexp"
"strings"
webhook_model "code.gitea.io/gitea/models/webhook"
@@ -286,3 +287,13 @@ func GetSlackPayload(p api.Payloader, event webhook_model.HookEventType, meta st
return convertPayloader(s, p, event)
}
+
+var slackChannel = regexp.MustCompile(`^#?[a-z0-9_-]{1,80}$`)
+
+// IsValidSlackChannel validates a channel name conforms to what slack expects:
+// https://api.slack.com/methods/conversations.rename#naming
+// Conversation names can only contain lowercase letters, numbers, hyphens, and underscores, and must be 80 characters or less.
+// Gitea accepts if it starts with a #.
+func IsValidSlackChannel(name string) bool {
+ return slackChannel.MatchString(name)
+}
diff --git a/services/webhook/slack_test.go b/services/webhook/slack_test.go
index 8278afb69a8c..0f08785d25e4 100644
--- a/services/webhook/slack_test.go
+++ b/services/webhook/slack_test.go
@@ -170,3 +170,22 @@ func TestSlackJSONPayload(t *testing.T) {
require.NoError(t, err)
assert.NotEmpty(t, json)
}
+
+func TestIsValidSlackChannel(t *testing.T) {
+ tt := []struct {
+ channelName string
+ expected bool
+ }{
+ {"gitea", true},
+ {"#gitea", true},
+ {" ", false},
+ {"#", false},
+ {" #", false},
+ {"gitea ", false},
+ {" gitea", false},
+ }
+
+ for _, v := range tt {
+ assert.Equal(t, v.expected, IsValidSlackChannel(v.channelName))
+ }
+}
diff --git a/services/webhook/webhook_test.go b/services/webhook/webhook_test.go
index 85fc39770e21..1887cc71fef1 100644
--- a/services/webhook/webhook_test.go
+++ b/services/webhook/webhook_test.go
@@ -30,7 +30,7 @@ func TestWebhook_GetSlackHook(t *testing.T) {
func TestPrepareWebhooks(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
hookTasks := []*webhook_model.HookTask{
{RepoID: repo.ID, HookID: 1, EventType: webhook_model.HookEventPush},
}
@@ -46,7 +46,7 @@ func TestPrepareWebhooks(t *testing.T) {
func TestPrepareWebhooksBranchFilterMatch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
hookTasks := []*webhook_model.HookTask{
{RepoID: repo.ID, HookID: 4, EventType: webhook_model.HookEventPush},
}
@@ -63,7 +63,7 @@ func TestPrepareWebhooksBranchFilterMatch(t *testing.T) {
func TestPrepareWebhooksBranchFilterNoMatch(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
hookTasks := []*webhook_model.HookTask{
{RepoID: repo.ID, HookID: 4, EventType: webhook_model.HookEventPush},
}
diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go
index 0c73074dbe27..1852ddbcb3f2 100644
--- a/services/wiki/wiki_test.go
+++ b/services/wiki/wiki_test.go
@@ -116,11 +116,11 @@ func TestWikiNameToFilenameToName(t *testing.T) {
func TestRepository_InitWiki(t *testing.T) {
unittest.PrepareTestEnv(t)
// repo1 already has a wiki
- repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
assert.NoError(t, InitWiki(git.DefaultContext, repo1))
// repo2 does not already have a wiki
- repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2}).(*repo_model.Repository)
+ repo2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 2})
assert.NoError(t, InitWiki(git.DefaultContext, repo2))
assert.True(t, repo2.HasWiki())
}
@@ -129,8 +129,8 @@ func TestRepository_AddWikiPage(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
const wikiContent = "This is the wiki content"
const commitMsg = "Commit message"
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
for _, wikiName := range []string{
"Another page",
"Here's a and a/slash",
@@ -174,8 +174,8 @@ func TestRepository_EditWikiPage(t *testing.T) {
const newWikiContent = "This is the new content"
const commitMsg = "Commit message"
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
for _, newWikiName := range []string{
"Home", // same name as before
"New home",
@@ -204,8 +204,8 @@ func TestRepository_EditWikiPage(t *testing.T) {
func TestRepository_DeleteWikiPage(t *testing.T) {
unittest.PrepareTestEnv(t)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
- doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
+ doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, DeleteWikiPage(git.DefaultContext, doer, repo, "Home"))
// Now need to show that the page has been added:
@@ -221,7 +221,7 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
func TestPrepareWikiFileName(t *testing.T) {
unittest.PrepareTestEnv(t)
- repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}).(*repo_model.Repository)
+ repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
gitRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath())
defer gitRepo.Close()
assert.NoError(t, err)
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index a55a797262a0..ccd1029cd80c 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -218,12 +218,7 @@
{{if .MailerEnabled}}
{{.locale.Tr "admin.config.mailer_name"}}
{{.Mailer.Name}}
- {{if eq .Mailer.MailerType "smtp"}}
- {{.locale.Tr "admin.config.mailer_disable_helo"}}
- {{if .DisableHelo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
- {{.locale.Tr "admin.config.mailer_host"}}
- {{.Mailer.Host}}
- {{else if eq .Mailer.MailerType "sendmail"}}
+ {{if eq .Mailer.Protocol "sendmail"}}
{{.locale.Tr "admin.config.mailer_use_sendmail"}}
{{svg "octicon-check"}}
{{.locale.Tr "admin.config.mailer_sendmail_path"}}
@@ -232,6 +227,18 @@
{{.Mailer.SendmailArgs}}
{{.locale.Tr "admin.config.mailer_sendmail_timeout"}}
{{.Mailer.SendmailTimeout}} {{.locale.Tr "tool.raw_seconds"}}
+ {{else if eq .Mailer.Protocol "dummy"}}
+ {{.locale.Tr "admin.config.mailer_use_dummy"}}
+ {{svg "octicon-check"}}
+ {{else}}{{/* SMTP family */}}
+ {{.locale.Tr "admin.config.mailer_protocol"}}
+ {{.Mailer.Protocol}}
+ {{.locale.Tr "admin.config.mailer_enable_helo"}}
+ {{if .Mailer.EnableHelo}}{{svg "octicon-check"}}{{else}}{{svg "octicon-x"}}{{end}}
+ {{.locale.Tr "admin.config.mailer_smtp_addr"}}
+ {{.Mailer.SMTPAddr}}
+ {{.locale.Tr "admin.config.mailer_smtp_port"}}
+ {{.Mailer.SMTPPort}}
{{end}}
{{.locale.Tr "admin.config.mailer_user"}}
{{if .Mailer.User}}{{.Mailer.User}}{{else}}(empty){{end}}
diff --git a/templates/admin/packages/list.tmpl b/templates/admin/packages/list.tmpl
index 18e8c5fed8da..61721532a441 100644
--- a/templates/admin/packages/list.tmpl
+++ b/templates/admin/packages/list.tmpl
@@ -21,6 +21,7 @@
Maven
npm
NuGet
+ Pub
PyPi
RubyGems
diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl
index 17cbef9f108a..dd2646b50a17 100644
--- a/templates/admin/user/edit.tmpl
+++ b/templates/admin/user/edit.tmpl
@@ -117,7 +117,7 @@