diff --git a/.golangci.yml b/.golangci.yml index 0f194097ed..c176d2115c 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,14 +13,17 @@ linters: - gocritic - govet - ineffassign + - mirror - nakedret - nolintlint + - perfsprint - revive - staticcheck - testifylint - unconvert - unparam - unused + - usestdlibvars - usetesting - wastedassign settings: @@ -92,10 +95,6 @@ linters: disable: - go-require - require-error - - equal-values - - empty - - formatter - - len usetesting: os-temp-dir: true exclusions: diff --git a/cmd/admin_auth_ldap_test.go b/cmd/admin_auth_ldap_test.go index bab42226ae..ea9a83ef76 100644 --- a/cmd/admin_auth_ldap_test.go +++ b/cmd/admin_auth_ldap_test.go @@ -229,11 +229,11 @@ func TestAddLdapBindDn(t *testing.T) { return nil }, updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { - assert.FailNow(t, "case %d: should not call updateAuthSource", n) + assert.FailNow(t, "updateAuthSource called", "case %d: should not call updateAuthSource", n) return nil }, getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { - assert.FailNow(t, "case %d: should not call getAuthSourceByID", n) + assert.FailNow(t, "getAuthSourceByID called", "case %d: should not call getAuthSourceByID", n) return nil, nil }, } @@ -460,11 +460,11 @@ func TestAddLdapSimpleAuth(t *testing.T) { return nil }, updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { - assert.FailNow(t, "case %d: should not call updateAuthSource", n) + assert.FailNow(t, "updateAuthSource called", "case %d: should not call updateAuthSource", n) return nil }, getAuthSourceByID: func(ctx context.Context, id int64) (*auth.Source, error) { - assert.FailNow(t, "case %d: should not call getAuthSourceByID", n) + assert.FailNow(t, "getAuthSourceById called", "case %d: should not call getAuthSourceByID", n) return nil, nil }, } @@ -925,7 +925,7 @@ func TestUpdateLdapBindDn(t *testing.T) { return nil }, createAuthSource: func(ctx context.Context, authSource *auth.Source) error { - assert.FailNow(t, "case %d: should not call createAuthSource", n) + assert.FailNow(t, "createAuthSource called", "case %d: should not call createAuthSource", n) return nil }, updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { @@ -1315,7 +1315,7 @@ func TestUpdateLdapSimpleAuth(t *testing.T) { return nil }, createAuthSource: func(ctx context.Context, authSource *auth.Source) error { - assert.FailNow(t, "case %d: should not call createAuthSource", n) + assert.FailNow(t, "createAuthSource called", "case %d: should not call createAuthSource", n) return nil }, updateAuthSource: func(ctx context.Context, authSource *auth.Source) error { diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go index 5e03d6ca3f..ebe0266d1f 100644 --- a/cmd/admin_user_create.go +++ b/cmd/admin_user_create.go @@ -7,6 +7,7 @@ import ( "context" "errors" "fmt" + "strings" auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" @@ -66,6 +67,16 @@ var microcmdUserCreate = &cli.Command{ Name: "access-token", Usage: "Generate access token for the user", }, + &cli.StringFlag{ + Name: "access-token-name", + Usage: `Name of the generated access token`, + Value: "gitea-admin", + }, + &cli.StringFlag{ + Name: "access-token-scopes", + Usage: `Scopes of the generated access token, comma separated. Examples: "all", "public-only,read:issue", "write:repository,write:user"`, + Value: "all", + }, &cli.BoolFlag{ Name: "restricted", Usage: "Make a restricted user account", @@ -187,23 +198,40 @@ func runCreateUser(c *cli.Context) error { IsRestricted: restricted, } + var accessTokenName string + var accessTokenScope auth_model.AccessTokenScope + if c.IsSet("access-token") { + accessTokenName = strings.TrimSpace(c.String("access-token-name")) + if accessTokenName == "" { + return errors.New("access-token-name cannot be empty") + } + var err error + accessTokenScope, err = auth_model.AccessTokenScope(c.String("access-token-scopes")).Normalize() + if err != nil { + return fmt.Errorf("invalid access token scope provided: %w", err) + } + if !accessTokenScope.HasPermissionScope() { + return errors.New("access token does not have any permission") + } + } else if c.IsSet("access-token-name") || c.IsSet("access-token-scopes") { + return errors.New("access-token-name and access-token-scopes flags are only valid when access-token flag is set") + } + + // arguments should be prepared before creating the user & access token, in case there is anything wrong + + // create the user if err := user_model.CreateUser(ctx, u, &user_model.Meta{}, overwriteDefault); err != nil { return fmt.Errorf("CreateUser: %w", err) } + fmt.Printf("New user '%s' has been successfully created!\n", username) - if c.Bool("access-token") { - t := &auth_model.AccessToken{ - Name: "gitea-admin", - UID: u.ID, - } - + // create the access token + if accessTokenScope != "" { + t := &auth_model.AccessToken{Name: accessTokenName, UID: u.ID, Scope: accessTokenScope} if err := auth_model.NewAccessToken(ctx, t); err != nil { return err } - fmt.Printf("Access token was successfully created... %s\n", t.Token) } - - fmt.Printf("New user '%s' has been successfully created!\n", username) return nil } diff --git a/cmd/admin_user_create_test.go b/cmd/admin_user_create_test.go index d8044e8de7..6fd6f8c226 100644 --- a/cmd/admin_user_create_test.go +++ b/cmd/admin_user_create_test.go @@ -8,6 +8,7 @@ import ( "strings" "testing" + auth_model "code.gitea.io/gitea/models/auth" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" @@ -22,6 +23,7 @@ func TestAdminUserCreate(t *testing.T) { reset := func() { require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.User{})) require.NoError(t, db.TruncateBeans(db.DefaultContext, &user_model.EmailAddress{})) + require.NoError(t, db.TruncateBeans(db.DefaultContext, &auth_model.AccessToken{})) } t.Run("MustChangePassword", func(t *testing.T) { @@ -48,11 +50,11 @@ func TestAdminUserCreate(t *testing.T) { assert.Equal(t, check{IsAdmin: false, MustChangePassword: false}, createCheck("u5", "--must-change-password=false")) }) - t.Run("UserType", func(t *testing.T) { - createUser := func(name, args string) error { - return app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %s@gitea.local %s", name, name, args))) - } + createUser := func(name, args string) error { + return app.Run(strings.Fields(fmt.Sprintf("./gitea admin user create --username %s --email %s@gitea.local %s", name, name, args))) + } + t.Run("UserType", func(t *testing.T) { reset() assert.ErrorContains(t, createUser("u", "--user-type invalid"), "invalid user type") assert.ErrorContains(t, createUser("u", "--user-type bot --password 123"), "can only be set for individual users") @@ -61,6 +63,58 @@ func TestAdminUserCreate(t *testing.T) { assert.NoError(t, createUser("u", "--user-type bot")) u := unittest.AssertExistsAndLoadBean(t, &user_model.User{LowerName: "u"}) assert.Equal(t, user_model.UserTypeBot, u.Type) - assert.Equal(t, "", u.Passwd) + assert.Empty(t, u.Passwd) + }) + + t.Run("AccessToken", func(t *testing.T) { + // no generated access token + reset() + assert.NoError(t, createUser("u", "--random-password")) + assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{})) + + // using "--access-token" only means "all" access + reset() + assert.NoError(t, createUser("u", "--random-password --access-token")) + assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 1, unittest.GetCount(t, &auth_model.AccessToken{})) + accessToken := unittest.AssertExistsAndLoadBean(t, &auth_model.AccessToken{Name: "gitea-admin"}) + hasScopes, err := accessToken.Scope.HasScope(auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteRepository) + assert.NoError(t, err) + assert.True(t, hasScopes) + + // using "--access-token" with name & scopes + reset() + assert.NoError(t, createUser("u", "--random-password --access-token --access-token-name new-token-name --access-token-scopes read:issue,read:user")) + assert.Equal(t, 1, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 1, unittest.GetCount(t, &auth_model.AccessToken{})) + accessToken = unittest.AssertExistsAndLoadBean(t, &auth_model.AccessToken{Name: "new-token-name"}) + hasScopes, err = accessToken.Scope.HasScope(auth_model.AccessTokenScopeReadIssue, auth_model.AccessTokenScopeReadUser) + assert.NoError(t, err) + assert.True(t, hasScopes) + hasScopes, err = accessToken.Scope.HasScope(auth_model.AccessTokenScopeWriteAdmin, auth_model.AccessTokenScopeWriteRepository) + assert.NoError(t, err) + assert.False(t, hasScopes) + + // using "--access-token-name" without "--access-token" + reset() + err = createUser("u", "--random-password --access-token-name new-token-name") + assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{})) + assert.ErrorContains(t, err, "access-token-name and access-token-scopes flags are only valid when access-token flag is set") + + // using "--access-token-scopes" without "--access-token" + reset() + err = createUser("u", "--random-password --access-token-scopes read:issue") + assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{})) + assert.ErrorContains(t, err, "access-token-name and access-token-scopes flags are only valid when access-token flag is set") + + // empty permission + reset() + err = createUser("u", "--random-password --access-token --access-token-scopes public-only") + assert.Equal(t, 0, unittest.GetCount(t, &user_model.User{})) + assert.Equal(t, 0, unittest.GetCount(t, &auth_model.AccessToken{})) + assert.ErrorContains(t, err, "access token does not have any permission") }) } diff --git a/cmd/admin_user_generate_access_token.go b/cmd/admin_user_generate_access_token.go index 6c2c10494e..f6db7a74bd 100644 --- a/cmd/admin_user_generate_access_token.go +++ b/cmd/admin_user_generate_access_token.go @@ -34,8 +34,8 @@ var microcmdUserGenerateAccessToken = &cli.Command{ }, &cli.StringFlag{ Name: "scopes", - Value: "", - Usage: "Comma separated list of scopes to apply to access token", + Value: "all", + Usage: `Comma separated list of scopes to apply to access token, examples: "all", "public-only,read:issue", "write:repository,write:user"`, }, }, Action: runGenerateAccessToken, @@ -43,7 +43,7 @@ var microcmdUserGenerateAccessToken = &cli.Command{ func runGenerateAccessToken(c *cli.Context) error { if !c.IsSet("username") { - return errors.New("You must provide a username to generate a token for") + return errors.New("you must provide a username to generate a token for") } ctx, cancel := installSignals() @@ -77,6 +77,9 @@ func runGenerateAccessToken(c *cli.Context) error { if err != nil { return fmt.Errorf("invalid access token scope provided: %w", err) } + if !accessTokenScope.HasPermissionScope() { + return errors.New("access token does not have any permission") + } t.Scope = accessTokenScope // create the token diff --git a/cmd/dump.go b/cmd/dump.go index ececc80f72..7d640b78fd 100644 --- a/cmd/dump.go +++ b/cmd/dump.go @@ -5,7 +5,6 @@ package cmd import ( - "fmt" "os" "path" "path/filepath" @@ -93,7 +92,7 @@ var CmdDump = &cli.Command{ }, &cli.StringFlag{ Name: "type", - Usage: fmt.Sprintf(`Dump output format, default to "zip", supported types: %s`, strings.Join(dump.SupportedOutputTypes, ", ")), + Usage: `Dump output format, default to "zip", supported types: ` + strings.Join(dump.SupportedOutputTypes, ", "), }, }, } diff --git a/cmd/main_test.go b/cmd/main_test.go index 3ec584d323..9573cacbd4 100644 --- a/cmd/main_test.go +++ b/cmd/main_test.go @@ -4,6 +4,7 @@ package cmd import ( + "errors" "fmt" "io" "path/filepath" @@ -127,18 +128,18 @@ func TestCliCmd(t *testing.T) { } func TestCliCmdError(t *testing.T) { - app := newTestApp(func(ctx *cli.Context) error { return fmt.Errorf("normal error") }) + app := newTestApp(func(ctx *cli.Context) error { return errors.New("normal error") }) r, err := runTestApp(app, "./gitea", "test-cmd") assert.Error(t, err) assert.Equal(t, 1, r.ExitCode) - assert.Equal(t, "", r.Stdout) + assert.Empty(t, r.Stdout) assert.Equal(t, "Command error: normal error\n", r.Stderr) app = newTestApp(func(ctx *cli.Context) error { return cli.Exit("exit error", 2) }) r, err = runTestApp(app, "./gitea", "test-cmd") assert.Error(t, err) assert.Equal(t, 2, r.ExitCode) - assert.Equal(t, "", r.Stdout) + assert.Empty(t, r.Stdout) assert.Equal(t, "exit error\n", r.Stderr) app = newTestApp(func(ctx *cli.Context) error { return nil }) @@ -146,12 +147,12 @@ func TestCliCmdError(t *testing.T) { assert.Error(t, err) assert.Equal(t, 1, r.ExitCode) assert.Equal(t, "Incorrect Usage: flag provided but not defined: -no-such\n\n", r.Stdout) - assert.Equal(t, "", r.Stderr) // the cli package's strange behavior, the error message is not in stderr .... + assert.Empty(t, r.Stderr) // the cli package's strange behavior, the error message is not in stderr .... app = newTestApp(func(ctx *cli.Context) error { return nil }) r, err = runTestApp(app, "./gitea", "test-cmd") assert.NoError(t, err) assert.Equal(t, -1, r.ExitCode) // the cli.OsExiter is not called - assert.Equal(t, "", r.Stdout) - assert.Equal(t, "", r.Stderr) + assert.Empty(t, r.Stdout) + assert.Empty(t, r.Stderr) } diff --git a/cmd/migrate_storage_test.go b/cmd/migrate_storage_test.go index f8fa95a927..6817867e28 100644 --- a/cmd/migrate_storage_test.go +++ b/cmd/migrate_storage_test.go @@ -69,6 +69,6 @@ func TestMigratePackages(t *testing.T) { entries, err := os.ReadDir(p) assert.NoError(t, err) assert.Len(t, entries, 2) - assert.EqualValues(t, "01", entries[0].Name()) - assert.EqualValues(t, "tmp", entries[1].Name()) + assert.Equal(t, "01", entries[0].Name()) + assert.Equal(t, "tmp", entries[1].Name()) } diff --git a/cmd/serv.go b/cmd/serv.go index 476fd9a2ea..b18508459f 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -173,7 +173,7 @@ func getLFSAuthToken(ctx context.Context, lfsVerb string, results *private.ServC if err != nil { return "", fail(ctx, "Failed to sign JWT Token", "Failed to sign JWT token: %v", err) } - return fmt.Sprintf("Bearer %s", tokenString), nil + return "Bearer " + tokenString, nil } func runServ(c *cli.Context) error { @@ -372,9 +372,9 @@ func runServ(c *cli.Context) error { repo_module.EnvPusherEmail+"="+results.UserEmail, repo_module.EnvPusherID+"="+strconv.FormatInt(results.UserID, 10), repo_module.EnvRepoID+"="+strconv.FormatInt(results.RepoID, 10), - repo_module.EnvPRID+"="+fmt.Sprintf("%d", 0), - repo_module.EnvDeployKeyID+"="+fmt.Sprintf("%d", results.DeployKeyID), - repo_module.EnvKeyID+"="+fmt.Sprintf("%d", results.KeyID), + repo_module.EnvPRID+"="+strconv.Itoa(0), + repo_module.EnvDeployKeyID+"="+strconv.FormatInt(results.DeployKeyID, 10), + repo_module.EnvKeyID+"="+strconv.FormatInt(results.KeyID, 10), repo_module.EnvAppURL+"="+setting.AppURL, ) // to avoid breaking, here only use the minimal environment variables for the "gitea serv" command. diff --git a/cmd/web_acme.go b/cmd/web_acme.go index 172dde913b..5f7a308334 100644 --- a/cmd/web_acme.go +++ b/cmd/web_acme.go @@ -136,7 +136,7 @@ func runACME(listenAddr string, m http.Handler) error { } func runLetsEncryptFallbackHandler(w http.ResponseWriter, r *http.Request) { - if r.Method != "GET" && r.Method != "HEAD" { + if r.Method != http.MethodGet && r.Method != http.MethodHead { http.Error(w, "Use HTTPS", http.StatusBadRequest) return } diff --git a/contrib/backport/backport.go b/contrib/backport/backport.go index eb19437445..9b30480300 100644 --- a/contrib/backport/backport.go +++ b/contrib/backport/backport.go @@ -6,6 +6,7 @@ package main import ( "context" + "errors" "fmt" "log" "net/http" @@ -158,7 +159,7 @@ func runBackport(c *cli.Context) error { args := c.Args().Slice() if len(args) == 0 && pr == "" { - return fmt.Errorf("no PR number provided\nProvide a PR number to backport") + return errors.New("no PR number provided\nProvide a PR number to backport") } else if len(args) != 1 && pr == "" { return fmt.Errorf("multiple PRs provided %v\nOnly a single PR can be backported at a time", args) } diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 0fc49accef..07a6ebdcf2 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -780,6 +780,9 @@ LEVEL = Info ;ALLOW_ONLY_EXTERNAL_REGISTRATION = false ;; ;; User must sign in to view anything. +;; It could be set to "expensive" to block anonymous users accessing some pages which consume a lot of resources, +;; for example: block anonymous AI crawlers from accessing repo code pages. +;; The "expensive" mode is experimental and subject to change. ;REQUIRE_SIGNIN_VIEW = false ;; ;; Mail notification @@ -1410,14 +1413,14 @@ LEVEL = Info ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; -;; Render soft line breaks as hard line breaks, which means a single newline character between -;; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not -;; necessary to force a line break. -;; Render soft line breaks as hard line breaks for comments -;ENABLE_HARD_LINE_BREAK_IN_COMMENTS = true -;; -;; Render soft line breaks as hard line breaks for markdown documents -;ENABLE_HARD_LINE_BREAK_IN_DOCUMENTS = false +;; Customize render options for different contexts. Set to "none" to disable the defaults, or use comma separated list: +;; * short-issue-pattern: recognized "#123" issue reference and render it as a link to the issue +;; * new-line-hard-break: render soft line breaks as hard line breaks, which means a single newline character between +;; paragraphs will cause a line break and adding trailing whitespace to paragraphs is not +;; necessary to force a line break. +;RENDER_OPTIONS_COMMENT = short-issue-pattern, new-line-hard-break +;RENDER_OPTIONS_WIKI = short-issue-pattern +;RENDER_OPTIONS_REPO_FILE = ;; ;; Comma separated list of custom URL-Schemes that are allowed as links when rendering Markdown ;; for example git,magnet,ftp (more at https://en.wikipedia.org/wiki/List_of_URI_schemes) @@ -1431,6 +1434,12 @@ LEVEL = Info ;; ;; Enables math inline and block detection ;ENABLE_MATH = true +;; +;; Enable delimiters for math code block detection. Set to "none" to disable all, +;; or use comma separated list: inline-dollar, inline-parentheses, block-dollar, block-square-brackets +;; Defaults to "inline-dollar,block-dollar" to follow GitHub's behavior. +;MATH_CODE_BLOCK_DETECTION = +;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docker/root/etc/s6/openssh/setup b/docker/root/etc/s6/openssh/setup index dbb3bafd35..6fbc599cc5 100755 --- a/docker/root/etc/s6/openssh/setup +++ b/docker/root/etc/s6/openssh/setup @@ -31,6 +31,18 @@ if [ -e /data/ssh/ssh_host_ecdsa_cert ]; then SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa_cert"} fi +if [ -e /data/ssh/ssh_host_ed25519-cert.pub ]; then + SSH_ED25519_CERT=${SSH_ED25519_CERT:-"/data/ssh/ssh_host_ed25519-cert.pub"} +fi + +if [ -e /data/ssh/ssh_host_rsa-cert.pub ]; then + SSH_RSA_CERT=${SSH_RSA_CERT:-"/data/ssh/ssh_host_rsa-cert.pub"} +fi + +if [ -e /data/ssh/ssh_host_ecdsa-cert.pub ]; then + SSH_ECDSA_CERT=${SSH_ECDSA_CERT:-"/data/ssh/ssh_host_ecdsa-cert.pub"} +fi + if [ -d /etc/ssh ]; then SSH_PORT=${SSH_PORT:-"22"} \ SSH_LISTEN_PORT=${SSH_LISTEN_PORT:-"${SSH_PORT}"} \ diff --git a/models/actions/run.go b/models/actions/run.go index 89f7f3e640..5f077940c5 100644 --- a/models/actions/run.go +++ b/models/actions/run.go @@ -5,6 +5,7 @@ package actions import ( "context" + "errors" "fmt" "slices" "strings" @@ -245,7 +246,7 @@ func CancelPreviousJobs(ctx context.Context, repoID int64, ref, workflowID strin // If the update affected 0 rows, it means the job has changed in the meantime, so we need to try again. if n == 0 { - return cancelledJobs, fmt.Errorf("job has changed, try again") + return cancelledJobs, errors.New("job has changed, try again") } cancelledJobs = append(cancelledJobs, job) @@ -412,7 +413,7 @@ func UpdateRun(ctx context.Context, run *ActionRun, cols ...string) error { return err } if affected == 0 { - return fmt.Errorf("run has changed") + return errors.New("run has changed") // It's impossible that the run is not found, since Gitea never deletes runs. } diff --git a/models/actions/runner_token_test.go b/models/actions/runner_token_test.go index 159805e5f7..21614b7086 100644 --- a/models/actions/runner_token_test.go +++ b/models/actions/runner_token_test.go @@ -17,7 +17,7 @@ func TestGetLatestRunnerToken(t *testing.T) { token := unittest.AssertExistsAndLoadBean(t, &ActionRunnerToken{ID: 3}) expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) assert.NoError(t, err) - assert.EqualValues(t, expectedToken, token) + assert.Equal(t, expectedToken, token) } func TestNewRunnerToken(t *testing.T) { @@ -26,7 +26,7 @@ func TestNewRunnerToken(t *testing.T) { assert.NoError(t, err) expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) assert.NoError(t, err) - assert.EqualValues(t, expectedToken, token) + assert.Equal(t, expectedToken, token) } func TestUpdateRunnerToken(t *testing.T) { @@ -36,5 +36,5 @@ func TestUpdateRunnerToken(t *testing.T) { assert.NoError(t, UpdateRunnerToken(db.DefaultContext, token)) expectedToken, err := GetLatestRunnerToken(db.DefaultContext, 1, 0) assert.NoError(t, err) - assert.EqualValues(t, expectedToken, token) + assert.Equal(t, expectedToken, token) } diff --git a/models/actions/task.go b/models/actions/task.go index 9f13ff94c9..43f11b2730 100644 --- a/models/actions/task.go +++ b/models/actions/task.go @@ -6,6 +6,7 @@ package actions import ( "context" "crypto/subtle" + "errors" "fmt" "time" @@ -361,7 +362,7 @@ func UpdateTaskByState(ctx context.Context, runnerID int64, state *runnerv1.Task } else if !has { return nil, util.ErrNotExist } else if runnerID != task.RunnerID { - return nil, fmt.Errorf("invalid runner for task") + return nil, errors.New("invalid runner for task") } if task.Status.IsDone() { diff --git a/models/activities/action_list.go b/models/activities/action_list.go index 6789ebcb99..b52cf7ee49 100644 --- a/models/activities/action_list.go +++ b/models/activities/action_list.go @@ -5,6 +5,7 @@ package activities import ( "context" + "errors" "fmt" "strconv" @@ -205,7 +206,7 @@ func (actions ActionList) LoadIssues(ctx context.Context) error { // GetFeeds returns actions according to the provided options func GetFeeds(ctx context.Context, opts GetFeedsOptions) (ActionList, int64, error) { if opts.RequestedUser == nil && opts.RequestedTeam == nil && opts.RequestedRepo == nil { - return nil, 0, fmt.Errorf("need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo") + return nil, 0, errors.New("need at least one of these filters: RequestedUser, RequestedTeam, RequestedRepo") } var err error diff --git a/models/activities/action_test.go b/models/activities/action_test.go index ee2a225a3e..ff311ac891 100644 --- a/models/activities/action_test.go +++ b/models/activities/action_test.go @@ -130,7 +130,7 @@ func TestDeleteIssueActions(t *testing.T) { // load an issue issue := unittest.AssertExistsAndLoadBean(t, &issue_model.Issue{ID: 4}) - assert.NotEqualValues(t, issue.ID, issue.Index) // it needs to use different ID/Index to test the DeleteIssueActions to delete some actions by IssueIndex + assert.NotEqual(t, issue.ID, issue.Index) // it needs to use different ID/Index to test the DeleteIssueActions to delete some actions by IssueIndex // insert a comment err := db.Insert(db.DefaultContext, &issue_model.Comment{Type: issue_model.CommentTypeComment, IssueID: issue.ID}) diff --git a/models/activities/notification_test.go b/models/activities/notification_test.go index 52f0eacba1..5d2a29bc36 100644 --- a/models/activities/notification_test.go +++ b/models/activities/notification_test.go @@ -44,11 +44,11 @@ func TestNotificationsForUser(t *testing.T) { assert.NoError(t, err) if assert.Len(t, notfs, 3) { assert.EqualValues(t, 5, notfs[0].ID) - assert.EqualValues(t, user.ID, notfs[0].UserID) + assert.Equal(t, user.ID, notfs[0].UserID) assert.EqualValues(t, 4, notfs[1].ID) - assert.EqualValues(t, user.ID, notfs[1].UserID) + assert.Equal(t, user.ID, notfs[1].UserID) assert.EqualValues(t, 2, notfs[2].ID) - assert.EqualValues(t, user.ID, notfs[2].UserID) + assert.Equal(t, user.ID, notfs[2].UserID) } } @@ -58,7 +58,7 @@ func TestNotification_GetRepo(t *testing.T) { repo, err := notf.GetRepo(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, repo, notf.Repository) - assert.EqualValues(t, notf.RepoID, repo.ID) + assert.Equal(t, notf.RepoID, repo.ID) } func TestNotification_GetIssue(t *testing.T) { @@ -67,7 +67,7 @@ func TestNotification_GetIssue(t *testing.T) { issue, err := notf.GetIssue(db.DefaultContext) assert.NoError(t, err) assert.Equal(t, issue, notf.Issue) - assert.EqualValues(t, notf.IssueID, issue.ID) + assert.Equal(t, notf.IssueID, issue.ID) } func TestGetNotificationCount(t *testing.T) { @@ -136,5 +136,5 @@ func TestSetIssueReadBy(t *testing.T) { nt, err := activities_model.GetIssueNotification(db.DefaultContext, user.ID, issue.ID) assert.NoError(t, err) - assert.EqualValues(t, activities_model.NotificationStatusRead, nt.Status) + assert.Equal(t, activities_model.NotificationStatusRead, nt.Status) } diff --git a/models/asymkey/error.go b/models/asymkey/error.go index 1ed6edd71a..b765624579 100644 --- a/models/asymkey/error.go +++ b/models/asymkey/error.go @@ -132,7 +132,7 @@ func IsErrGPGKeyParsing(err error) bool { } func (err ErrGPGKeyParsing) Error() string { - return fmt.Sprintf("failed to parse gpg key %s", err.ParseError.Error()) + return "failed to parse gpg key " + err.ParseError.Error() } // ErrGPGKeyNotExist represents a "GPGKeyNotExist" kind of error. diff --git a/models/asymkey/gpg_key.go b/models/asymkey/gpg_key.go index 7f35a96a59..24c76f7b5c 100644 --- a/models/asymkey/gpg_key.go +++ b/models/asymkey/gpg_key.go @@ -5,6 +5,7 @@ package asymkey import ( "context" + "errors" "fmt" "strings" "time" @@ -207,7 +208,7 @@ func parseGPGKey(ctx context.Context, ownerID int64, e *openpgp.Entity, verified // deleteGPGKey does the actual key deletion func deleteGPGKey(ctx context.Context, keyID string) (int64, error) { if keyID == "" { - return 0, fmt.Errorf("empty KeyId forbidden") // Should never happen but just to be sure + return 0, errors.New("empty KeyId forbidden") // Should never happen but just to be sure } // Delete imported key n, err := db.GetEngine(ctx).Where("key_id=?", keyID).Delete(new(GPGKeyImport)) diff --git a/models/asymkey/gpg_key_commit_verification.go b/models/asymkey/gpg_key_commit_verification.go index 1591cd5068..39ec893606 100644 --- a/models/asymkey/gpg_key_commit_verification.go +++ b/models/asymkey/gpg_key_commit_verification.go @@ -4,6 +4,7 @@ package asymkey import ( + "errors" "fmt" "hash" @@ -68,7 +69,7 @@ const ( func verifySign(s *packet.Signature, h hash.Hash, k *GPGKey) error { // Check if key can sign if !k.CanSign { - return fmt.Errorf("key can not sign") + return errors.New("key can not sign") } // Decode key pkey, err := base64DecPubKey(k.Content) diff --git a/models/asymkey/gpg_key_common.go b/models/asymkey/gpg_key_common.go index 1291cbc542..76f52a3ca4 100644 --- a/models/asymkey/gpg_key_common.go +++ b/models/asymkey/gpg_key_common.go @@ -7,6 +7,7 @@ import ( "bytes" "crypto" "encoding/base64" + "errors" "fmt" "hash" "io" @@ -75,7 +76,7 @@ func base64DecPubKey(content string) (*packet.PublicKey, error) { // Check type pkey, ok := p.(*packet.PublicKey) if !ok { - return nil, fmt.Errorf("key is not a public key") + return nil, errors.New("key is not a public key") } return pkey, nil } @@ -122,15 +123,15 @@ func readArmoredSign(r io.Reader) (body io.Reader, err error) { func ExtractSignature(s string) (*packet.Signature, error) { r, err := readArmoredSign(strings.NewReader(s)) if err != nil { - return nil, fmt.Errorf("Failed to read signature armor") + return nil, errors.New("Failed to read signature armor") } p, err := packet.Read(r) if err != nil { - return nil, fmt.Errorf("Failed to read signature packet") + return nil, errors.New("Failed to read signature packet") } sig, ok := p.(*packet.Signature) if !ok { - return nil, fmt.Errorf("Packet is not a signature") + return nil, errors.New("Packet is not a signature") } return sig, nil } diff --git a/models/asymkey/ssh_key_commit_verification.go b/models/asymkey/ssh_key_commit_verification.go deleted file mode 100644 index 27c6df3578..0000000000 --- a/models/asymkey/ssh_key_commit_verification.go +++ /dev/null @@ -1,80 +0,0 @@ -// Copyright 2021 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package asymkey - -import ( - "bytes" - "context" - "fmt" - "strings" - - "code.gitea.io/gitea/models/db" - user_model "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/log" - - "github.com/42wim/sshsig" -) - -// ParseCommitWithSSHSignature check if signature is good against keystore. -func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *user_model.User) *CommitVerification { - // Now try to associate the signature with the committer, if present - if committer.ID != 0 { - keys, err := db.Find[PublicKey](ctx, FindPublicKeyOptions{ - OwnerID: committer.ID, - NotKeytype: KeyTypePrincipal, - }) - if err != nil { // Skipping failed to get ssh keys of user - log.Error("ListPublicKeys: %v", err) - return &CommitVerification{ - CommittingUser: committer, - Verified: false, - Reason: "gpg.error.failed_retrieval_gpg_keys", - } - } - - committerEmailAddresses, err := user_model.GetEmailAddresses(ctx, committer.ID) - if err != nil { - log.Error("GetEmailAddresses: %v", err) - } - - activated := false - for _, e := range committerEmailAddresses { - if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) { - activated = true - break - } - } - - for _, k := range keys { - if k.Verified && activated { - commitVerification := verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, k, committer, committer, c.Committer.Email) - if commitVerification != nil { - return commitVerification - } - } - } - } - - return &CommitVerification{ - CommittingUser: committer, - Verified: false, - Reason: NoKeyFound, - } -} - -func verifySSHCommitVerification(sig, payload string, k *PublicKey, committer, signer *user_model.User, email string) *CommitVerification { - if err := sshsig.Verify(bytes.NewBuffer([]byte(payload)), []byte(sig), []byte(k.Content), "git"); err != nil { - return nil - } - - return &CommitVerification{ // Everything is ok - CommittingUser: committer, - Verified: true, - Reason: fmt.Sprintf("%s / %s", signer.Name, k.Fingerprint), - SigningUser: signer, - SigningSSHKey: k, - SigningEmail: email, - } -} diff --git a/models/asymkey/ssh_key_parse.go b/models/asymkey/ssh_key_parse.go index 94b1cf112b..c843525718 100644 --- a/models/asymkey/ssh_key_parse.go +++ b/models/asymkey/ssh_key_parse.go @@ -10,6 +10,7 @@ import ( "encoding/base64" "encoding/binary" "encoding/pem" + "errors" "fmt" "math/big" "os" @@ -93,7 +94,7 @@ func parseKeyString(content string) (string, error) { block, _ := pem.Decode([]byte(content)) if block == nil { - return "", fmt.Errorf("failed to parse PEM block containing the public key") + return "", errors.New("failed to parse PEM block containing the public key") } if strings.Contains(block.Type, "PRIVATE") { return "", ErrKeyIsPrivate diff --git a/models/asymkey/ssh_key_test.go b/models/asymkey/ssh_key_test.go index 3650f1892f..b33d16030d 100644 --- a/models/asymkey/ssh_key_test.go +++ b/models/asymkey/ssh_key_test.go @@ -18,6 +18,7 @@ import ( "github.com/42wim/sshsig" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func Test_SSHParsePublicKey(t *testing.T) { @@ -42,7 +43,7 @@ func Test_SSHParsePublicKey(t *testing.T) { keyTypeN, lengthN, err := SSHNativeParsePublicKey(tc.content) assert.NoError(t, err) assert.Equal(t, tc.keyType, keyTypeN) - assert.EqualValues(t, tc.length, lengthN) + assert.Equal(t, tc.length, lengthN) }) if tc.skipSSHKeygen { return @@ -52,19 +53,18 @@ func Test_SSHParsePublicKey(t *testing.T) { if err != nil { // Some servers do not support ecdsa format. if !strings.Contains(err.Error(), "line 1 too long:") { - assert.FailNow(t, "%v", err) + require.NoError(t, err) } } assert.Equal(t, tc.keyType, keyTypeK) - assert.EqualValues(t, tc.length, lengthK) + assert.Equal(t, tc.length, lengthK) }) t.Run("SSHParseKeyNative", func(t *testing.T) { keyTypeK, lengthK, err := SSHNativeParsePublicKey(tc.content) - if err != nil { - assert.FailNow(t, "%v", err) - } + require.NoError(t, err) + assert.Equal(t, tc.keyType, keyTypeK) - assert.EqualValues(t, tc.length, lengthK) + assert.Equal(t, tc.length, lengthK) }) }) } diff --git a/models/asymkey/ssh_key_verify.go b/models/asymkey/ssh_key_verify.go index 208288c77b..605ffe9096 100644 --- a/models/asymkey/ssh_key_verify.go +++ b/models/asymkey/ssh_key_verify.go @@ -4,8 +4,8 @@ package asymkey import ( - "bytes" "context" + "strings" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/log" @@ -30,11 +30,11 @@ func VerifySSHKey(ctx context.Context, ownerID int64, fingerprint, token, signat return "", ErrKeyNotExist{} } - err = sshsig.Verify(bytes.NewBuffer([]byte(token)), []byte(signature), []byte(key.Content), "gitea") + err = sshsig.Verify(strings.NewReader(token), []byte(signature), []byte(key.Content), "gitea") if err != nil { // edge case for Windows based shells that will add CR LF if piped to ssh-keygen command // see https://github.com/PowerShell/PowerShell/issues/5974 - if sshsig.Verify(bytes.NewBuffer([]byte(token+"\r\n")), []byte(signature), []byte(key.Content), "gitea") != nil { + if sshsig.Verify(strings.NewReader(token+"\r\n"), []byte(signature), []byte(key.Content), "gitea") != nil { log.Error("Unable to validate token signature. Error: %v", err) return "", ErrSSHInvalidTokenSignature{ Fingerprint: key.Fingerprint, diff --git a/models/auth/access_token_scope.go b/models/auth/access_token_scope.go index 0e5b2e96e6..2293fd89a0 100644 --- a/models/auth/access_token_scope.go +++ b/models/auth/access_token_scope.go @@ -295,6 +295,10 @@ func (s AccessTokenScope) Normalize() (AccessTokenScope, error) { return bitmap.toScope(), nil } +func (s AccessTokenScope) HasPermissionScope() bool { + return s != "" && s != AccessTokenScopePublicOnly +} + // PublicOnly checks if this token scope is limited to public resources func (s AccessTokenScope) PublicOnly() (bool, error) { bitmap, err := s.parse() diff --git a/models/auth/access_token_scope_test.go b/models/auth/access_token_scope_test.go index 9e4aa83633..b93c25528f 100644 --- a/models/auth/access_token_scope_test.go +++ b/models/auth/access_token_scope_test.go @@ -28,11 +28,11 @@ func TestAccessTokenScope_Normalize(t *testing.T) { for _, scope := range GetAccessTokenCategories() { tests = append(tests, - scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%s", scope)), AccessTokenScope(fmt.Sprintf("read:%s", scope)), nil}, - scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, - scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%[1]s,read:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, - scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,write:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, - scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,write:%[1]s,write:%[1]s", scope)), AccessTokenScope(fmt.Sprintf("write:%s", scope)), nil}, + scopeTestNormalize{AccessTokenScope("read:" + scope), AccessTokenScope("read:" + scope), nil}, + scopeTestNormalize{AccessTokenScope("write:" + scope), AccessTokenScope("write:" + scope), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("write:%[1]s,read:%[1]s", scope)), AccessTokenScope("write:" + scope), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,write:%[1]s", scope)), AccessTokenScope("write:" + scope), nil}, + scopeTestNormalize{AccessTokenScope(fmt.Sprintf("read:%[1]s,write:%[1]s,write:%[1]s", scope)), AccessTokenScope("write:" + scope), nil}, ) } @@ -63,20 +63,20 @@ func TestAccessTokenScope_HasScope(t *testing.T) { for _, scope := range GetAccessTokenCategories() { tests = append(tests, scopeTestHasScope{ - AccessTokenScope(fmt.Sprintf("read:%s", scope)), - AccessTokenScope(fmt.Sprintf("read:%s", scope)), true, nil, + AccessTokenScope("read:" + scope), + AccessTokenScope("read:" + scope), true, nil, }, scopeTestHasScope{ - AccessTokenScope(fmt.Sprintf("write:%s", scope)), - AccessTokenScope(fmt.Sprintf("write:%s", scope)), true, nil, + AccessTokenScope("write:" + scope), + AccessTokenScope("write:" + scope), true, nil, }, scopeTestHasScope{ - AccessTokenScope(fmt.Sprintf("write:%s", scope)), - AccessTokenScope(fmt.Sprintf("read:%s", scope)), true, nil, + AccessTokenScope("write:" + scope), + AccessTokenScope("read:" + scope), true, nil, }, scopeTestHasScope{ - AccessTokenScope(fmt.Sprintf("read:%s", scope)), - AccessTokenScope(fmt.Sprintf("write:%s", scope)), false, nil, + AccessTokenScope("read:" + scope), + AccessTokenScope("write:" + scope), false, nil, }, ) } diff --git a/models/auth/oauth2_test.go b/models/auth/oauth2_test.go index fa89a58b14..c6626b283e 100644 --- a/models/auth/oauth2_test.go +++ b/models/auth/oauth2_test.go @@ -126,7 +126,7 @@ func TestOAuth2Application_CreateGrant(t *testing.T) { assert.NotNil(t, grant) assert.Equal(t, int64(2), grant.UserID) assert.Equal(t, int64(1), grant.ApplicationID) - assert.Equal(t, "", grant.Scope) + assert.Empty(t, grant.Scope) } //////////////////// Grant diff --git a/models/db/context_test.go b/models/db/context_test.go index e8c6b74d93..a6bd11d2ae 100644 --- a/models/db/context_test.go +++ b/models/db/context_test.go @@ -118,7 +118,7 @@ func TestContextSafety(t *testing.T) { }) return nil }) - assert.EqualValues(t, testCount, actualCount) + assert.Equal(t, testCount, actualCount) // deny the bad usages assert.PanicsWithError(t, "using database context in an iterator would cause corrupted results", func() { diff --git a/models/db/engine.go b/models/db/engine.go index 91015f7038..ba287d58f0 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -127,7 +127,7 @@ func IsTableNotEmpty(beanOrTableName any) (bool, error) { // DeleteAllRecords will delete all the records of this table func DeleteAllRecords(tableName string) error { - _, err := xormEngine.Exec(fmt.Sprintf("DELETE FROM %s", tableName)) + _, err := xormEngine.Exec("DELETE FROM " + tableName) return err } diff --git a/models/db/engine_test.go b/models/db/engine_test.go index 10a1a33ff0..a236f83735 100644 --- a/models/db/engine_test.go +++ b/models/db/engine_test.go @@ -52,7 +52,7 @@ func TestDeleteOrphanedObjects(t *testing.T) { countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) assert.NoError(t, err) - assert.EqualValues(t, countBefore, countAfter) + assert.Equal(t, countBefore, countAfter) } func TestPrimaryKeys(t *testing.T) { diff --git a/models/db/error.go b/models/db/error.go index 665e970e17..d47c7adac4 100644 --- a/models/db/error.go +++ b/models/db/error.go @@ -65,7 +65,7 @@ func (err ErrNotExist) Error() string { if err.ID != 0 { return fmt.Sprintf("%s does not exist [id: %d]", name, err.ID) } - return fmt.Sprintf("%s does not exist", name) + return name + " does not exist" } // Unwrap unwraps this as a ErrNotExist err diff --git a/models/db/list_test.go b/models/db/list_test.go index 45194611f8..170473a968 100644 --- a/models/db/list_test.go +++ b/models/db/list_test.go @@ -47,6 +47,6 @@ func TestFind(t *testing.T) { repoUnits, newCnt, err := db.FindAndCount[repo_model.RepoUnit](db.DefaultContext, opts) assert.NoError(t, err) - assert.EqualValues(t, cnt, newCnt) + assert.Equal(t, cnt, newCnt) assert.Len(t, repoUnits, repoUnitCount) } diff --git a/models/dbfs/dbfs_test.go b/models/dbfs/dbfs_test.go index 96cb1014c7..0257d2bd15 100644 --- a/models/dbfs/dbfs_test.go +++ b/models/dbfs/dbfs_test.go @@ -31,15 +31,15 @@ func TestDbfsBasic(t *testing.T) { n, err := f.Write([]byte("0123456789")) // blocks: 0123 4567 89 assert.NoError(t, err) - assert.EqualValues(t, 10, n) + assert.Equal(t, 10, n) _, err = f.Seek(0, io.SeekStart) assert.NoError(t, err) buf, err := io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, 10, n) - assert.EqualValues(t, "0123456789", string(buf)) + assert.Equal(t, 10, n) + assert.Equal(t, "0123456789", string(buf)) // write some new data _, err = f.Seek(1, io.SeekStart) @@ -50,14 +50,14 @@ func TestDbfsBasic(t *testing.T) { // read from offset buf, err = io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "9", string(buf)) + assert.Equal(t, "9", string(buf)) // read all _, err = f.Seek(0, io.SeekStart) assert.NoError(t, err) buf, err = io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "0bcdefghi9", string(buf)) + assert.Equal(t, "0bcdefghi9", string(buf)) // write to new size _, err = f.Seek(-1, io.SeekEnd) @@ -68,7 +68,7 @@ func TestDbfsBasic(t *testing.T) { assert.NoError(t, err) buf, err = io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "0bcdefghiJKLMNOP", string(buf)) + assert.Equal(t, "0bcdefghiJKLMNOP", string(buf)) // write beyond EOF and fill with zero _, err = f.Seek(5, io.SeekCurrent) @@ -79,7 +79,7 @@ func TestDbfsBasic(t *testing.T) { assert.NoError(t, err) buf, err = io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00\x00\x00xyzu", string(buf)) + assert.Equal(t, "0bcdefghiJKLMNOP\x00\x00\x00\x00\x00xyzu", string(buf)) // write to the block with zeros _, err = f.Seek(-6, io.SeekCurrent) @@ -90,7 +90,7 @@ func TestDbfsBasic(t *testing.T) { assert.NoError(t, err) buf, err = io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "0bcdefghiJKLMNOP\x00\x00\x00ABCDzu", string(buf)) + assert.Equal(t, "0bcdefghiJKLMNOP\x00\x00\x00ABCDzu", string(buf)) assert.NoError(t, f.Close()) @@ -117,7 +117,7 @@ func TestDbfsBasic(t *testing.T) { assert.NoError(t, err) stat, err := f.Stat() assert.NoError(t, err) - assert.EqualValues(t, "test.txt", stat.Name()) + assert.Equal(t, "test.txt", stat.Name()) assert.EqualValues(t, 0, stat.Size()) _, err = f.Write([]byte("0123456789")) assert.NoError(t, err) @@ -144,7 +144,7 @@ func TestDbfsReadWrite(t *testing.T) { line, err := f2r.ReadString('\n') assert.NoError(t, err) - assert.EqualValues(t, "line 1\n", line) + assert.Equal(t, "line 1\n", line) _, err = f2r.ReadString('\n') assert.ErrorIs(t, err, io.EOF) @@ -153,7 +153,7 @@ func TestDbfsReadWrite(t *testing.T) { line, err = f2r.ReadString('\n') assert.NoError(t, err) - assert.EqualValues(t, "line 2\n", line) + assert.Equal(t, "line 2\n", line) _, err = f2r.ReadString('\n') assert.ErrorIs(t, err, io.EOF) } @@ -186,5 +186,5 @@ func TestDbfsSeekWrite(t *testing.T) { buf, err := io.ReadAll(fr) assert.NoError(t, err) - assert.EqualValues(t, "111333", string(buf)) + assert.Equal(t, "111333", string(buf)) } diff --git a/models/fixtures/branch.yml b/models/fixtures/branch.yml index 17b1869ab6..6536e1dda7 100644 --- a/models/fixtures/branch.yml +++ b/models/fixtures/branch.yml @@ -93,3 +93,111 @@ is_deleted: false deleted_by_id: 0 deleted_unix: 0 + +- + id: 16 + repo_id: 16 + name: 'master' + commit_id: '69554a64c1e6030f051e5c3f94bfbd773cd6a324' + commit_message: 'not signed commit' + commit_time: 1502042309 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 17 + repo_id: 16 + name: 'not-signed' + commit_id: '69554a64c1e6030f051e5c3f94bfbd773cd6a324' + commit_message: 'not signed commit' + commit_time: 1502042309 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 18 + repo_id: 16 + name: 'good-sign-not-yet-validated' + commit_id: '27566bd5738fc8b4e3fef3c5e72cce608537bd95' + commit_message: 'good signed commit (with not yet validated email)' + commit_time: 1502042234 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 19 + repo_id: 16 + name: 'good-sign' + commit_id: 'f27c2b2b03dcab38beaf89b0ab4ff61f6de63441' + commit_message: 'good signed commit' + commit_time: 1502042101 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 20 + repo_id: 1 + name: 'feature/1' + commit_id: '65f1bf27bc3bf70f64657658635e66094edbcb4d' + commit_message: 'Initial commit' + commit_time: 1489950479 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 21 + repo_id: 49 + name: 'master' + commit_id: 'aacbdfe9e1c4b47f60abe81849045fa4e96f1d75' + commit_message: "Add 'test/test.txt'" + commit_time: 1572535577 + pusher_id: 2 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 22 + repo_id: 1 + name: 'develop' + commit_id: '65f1bf27bc3bf70f64657658635e66094edbcb4d' + commit_message: "Initial commit" + commit_time: 1489927679 + pusher_id: 1 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 23 + repo_id: 3 + name: 'master' + commit_id: '2a47ca4b614a9f5a43abbd5ad851a54a616ffee6' + commit_message: "init project" + commit_time: 1497448461 + pusher_id: 1 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 + +- + id: 24 + repo_id: 3 + name: 'test_branch' + commit_id: 'd22b4d4daa5be07329fcef6ed458f00cf3392da0' + commit_message: "test commit" + commit_time: 1602935385 + pusher_id: 1 + is_deleted: false + deleted_by_id: 0 + deleted_unix: 0 diff --git a/models/fixtures/repo_transfer.yml b/models/fixtures/repo_transfer.yml index db92c95248..b12e6b207f 100644 --- a/models/fixtures/repo_transfer.yml +++ b/models/fixtures/repo_transfer.yml @@ -21,3 +21,11 @@ repo_id: 32 created_unix: 1553610671 updated_unix: 1553610671 + +- + id: 4 + doer_id: 3 + recipient_id: 1 + repo_id: 5 + created_unix: 1553610671 + updated_unix: 1553610671 diff --git a/models/git/branch.go b/models/git/branch.go index d1caa35947..9ac6c45578 100644 --- a/models/git/branch.go +++ b/models/git/branch.go @@ -173,6 +173,18 @@ func GetBranch(ctx context.Context, repoID int64, branchName string) (*Branch, e return &branch, nil } +// IsBranchExist returns true if the branch exists in the repository. +func IsBranchExist(ctx context.Context, repoID int64, branchName string) (bool, error) { + var branch Branch + has, err := db.GetEngine(ctx).Where("repo_id=?", repoID).And("name=?", branchName).Get(&branch) + if err != nil { + return false, err + } else if !has { + return false, nil + } + return !branch.IsDeleted, nil +} + func GetBranches(ctx context.Context, repoID int64, branchNames []string, includeDeleted bool) ([]*Branch, error) { branches := make([]*Branch, 0, len(branchNames)) diff --git a/models/git/branch_test.go b/models/git/branch_test.go index b8ea663e81..252dcc5690 100644 --- a/models/git/branch_test.go +++ b/models/git/branch_test.go @@ -21,7 +21,7 @@ import ( func TestAddDeletedBranch(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1}) - assert.EqualValues(t, git.Sha1ObjectFormat.Name(), repo.ObjectFormatName) + assert.Equal(t, git.Sha1ObjectFormat.Name(), repo.ObjectFormatName) firstBranch := unittest.AssertExistsAndLoadBean(t, &git_model.Branch{ID: 1}) assert.True(t, firstBranch.IsDeleted) diff --git a/models/git/commit_status.go b/models/git/commit_status.go index d1c94aa023..b978476c4b 100644 --- a/models/git/commit_status.go +++ b/models/git/commit_status.go @@ -222,7 +222,7 @@ func (status *CommitStatus) HideActionsURL(ctx context.Context) { } } - prefix := fmt.Sprintf("%s/actions", status.Repo.Link()) + prefix := status.Repo.Link() + "/actions" if strings.HasPrefix(status.TargetURL, prefix) { status.TargetURL = "" } diff --git a/models/git/protected_branch_list_test.go b/models/git/protected_branch_list_test.go index a46402c543..298c2fa074 100644 --- a/models/git/protected_branch_list_test.go +++ b/models/git/protected_branch_list_test.go @@ -70,7 +70,7 @@ func TestBranchRuleMatchPriority(t *testing.T) { assert.Error(t, fmt.Errorf("no matched rules but expected %s[%d]", kase.Rules[kase.ExpectedMatchIdx], kase.ExpectedMatchIdx)) } } else { - assert.EqualValues(t, kase.Rules[kase.ExpectedMatchIdx], matchedPB.RuleName) + assert.Equal(t, kase.Rules[kase.ExpectedMatchIdx], matchedPB.RuleName) } } } diff --git a/models/git/protected_branch_test.go b/models/git/protected_branch_test.go index e1c91d927d..367992081d 100644 --- a/models/git/protected_branch_test.go +++ b/models/git/protected_branch_test.go @@ -74,7 +74,7 @@ func TestBranchRuleMatch(t *testing.T) { } else { infact = " not" } - assert.EqualValues(t, kase.ExpectedMatch, pb.Match(kase.BranchName), + assert.Equal(t, kase.ExpectedMatch, pb.Match(kase.BranchName), "%s should%s match %s but it is%s", kase.BranchName, should, kase.Rule, infact, ) } diff --git a/models/issues/comment_test.go b/models/issues/comment_test.go index ae0bc3ce17..c08e3b970d 100644 --- a/models/issues/comment_test.go +++ b/models/issues/comment_test.go @@ -34,10 +34,10 @@ func TestCreateComment(t *testing.T) { assert.NoError(t, err) then := time.Now().Unix() - assert.EqualValues(t, issues_model.CommentTypeComment, comment.Type) - assert.EqualValues(t, "Hello", comment.Content) - assert.EqualValues(t, issue.ID, comment.IssueID) - assert.EqualValues(t, doer.ID, comment.PosterID) + assert.Equal(t, issues_model.CommentTypeComment, comment.Type) + assert.Equal(t, "Hello", comment.Content) + assert.Equal(t, issue.ID, comment.IssueID) + assert.Equal(t, doer.ID, comment.PosterID) unittest.AssertInt64InRange(t, now, then, int64(comment.CreatedUnix)) unittest.AssertExistsAndLoadBean(t, comment) // assert actually added to DB @@ -58,9 +58,9 @@ func Test_UpdateCommentAttachment(t *testing.T) { assert.NoError(t, err) attachment2 := unittest.AssertExistsAndLoadBean(t, &repo_model.Attachment{ID: attachment.ID}) - assert.EqualValues(t, attachment.Name, attachment2.Name) - assert.EqualValues(t, comment.ID, attachment2.CommentID) - assert.EqualValues(t, comment.IssueID, attachment2.IssueID) + assert.Equal(t, attachment.Name, attachment2.Name) + assert.Equal(t, comment.ID, attachment2.CommentID) + assert.Equal(t, comment.IssueID, attachment2.IssueID) } func TestFetchCodeComments(t *testing.T) { @@ -111,7 +111,7 @@ func TestMigrate_InsertIssueComments(t *testing.T) { assert.NoError(t, err) issueModified := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 1}) - assert.EqualValues(t, issue.NumComments+1, issueModified.NumComments) + assert.Equal(t, issue.NumComments+1, issueModified.NumComments) unittest.CheckConsistencyFor(t, &issues_model.Issue{}) } @@ -122,5 +122,5 @@ func Test_UpdateIssueNumComments(t *testing.T) { assert.NoError(t, issues_model.UpdateIssueNumComments(db.DefaultContext, issue2.ID)) issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) - assert.EqualValues(t, 1, issue2.NumComments) + assert.Equal(t, 1, issue2.NumComments) } diff --git a/models/issues/issue.go b/models/issues/issue.go index 5204f27faf..a86d50ca9d 100644 --- a/models/issues/issue.go +++ b/models/issues/issue.go @@ -10,6 +10,7 @@ import ( "html/template" "regexp" "slices" + "strconv" "code.gitea.io/gitea/models/db" project_model "code.gitea.io/gitea/models/project" @@ -815,7 +816,7 @@ func ChangeIssueTimeEstimate(ctx context.Context, issue *Issue, doer *user_model Doer: doer, Repo: issue.Repo, Issue: issue, - Content: fmt.Sprintf("%d", timeEstimate), + Content: strconv.FormatInt(timeEstimate, 10), } if _, err := CreateComment(ctx, opts); err != nil { return fmt.Errorf("createComment: %w", err) diff --git a/models/issues/issue_list_test.go b/models/issues/issue_list_test.go index 9069e1012d..5b4d2ca5ab 100644 --- a/models/issues/issue_list_test.go +++ b/models/issues/issue_list_test.go @@ -27,7 +27,7 @@ func TestIssueList_LoadRepositories(t *testing.T) { assert.NoError(t, err) assert.Len(t, repos, 2) for _, issue := range issueList { - assert.EqualValues(t, issue.RepoID, issue.Repo.ID) + assert.Equal(t, issue.RepoID, issue.Repo.ID) } } @@ -41,28 +41,28 @@ func TestIssueList_LoadAttributes(t *testing.T) { assert.NoError(t, issueList.LoadAttributes(db.DefaultContext)) for _, issue := range issueList { - assert.EqualValues(t, issue.RepoID, issue.Repo.ID) + assert.Equal(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { - assert.EqualValues(t, issue.RepoID, label.RepoID) + assert.Equal(t, issue.RepoID, label.RepoID) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } if issue.PosterID > 0 { - assert.EqualValues(t, issue.PosterID, issue.Poster.ID) + assert.Equal(t, issue.PosterID, issue.Poster.ID) } if issue.AssigneeID > 0 { - assert.EqualValues(t, issue.AssigneeID, issue.Assignee.ID) + assert.Equal(t, issue.AssigneeID, issue.Assignee.ID) } if issue.MilestoneID > 0 { - assert.EqualValues(t, issue.MilestoneID, issue.Milestone.ID) + assert.Equal(t, issue.MilestoneID, issue.Milestone.ID) } if issue.IsPull { - assert.EqualValues(t, issue.ID, issue.PullRequest.IssueID) + assert.Equal(t, issue.ID, issue.PullRequest.IssueID) } for _, attachment := range issue.Attachments { - assert.EqualValues(t, issue.ID, attachment.IssueID) + assert.Equal(t, issue.ID, attachment.IssueID) } for _, comment := range issue.Comments { - assert.EqualValues(t, issue.ID, comment.IssueID) + assert.Equal(t, issue.ID, comment.IssueID) } if issue.ID == int64(1) { assert.Equal(t, int64(400), issue.TotalTrackedTime) diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go index c32aa26b2b..18571e3aaa 100644 --- a/models/issues/issue_test.go +++ b/models/issues/issue_test.go @@ -141,8 +141,8 @@ func TestUpdateIssueCols(t *testing.T) { then := time.Now().Unix() updatedIssue := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: issue.ID}) - assert.EqualValues(t, newTitle, updatedIssue.Title) - assert.EqualValues(t, prevContent, updatedIssue.Content) + assert.Equal(t, newTitle, updatedIssue.Title) + assert.Equal(t, prevContent, updatedIssue.Content) unittest.AssertInt64InRange(t, now, then, int64(updatedIssue.UpdatedUnix)) } @@ -201,7 +201,7 @@ func TestIssues(t *testing.T) { assert.NoError(t, err) if assert.Len(t, issues, len(test.ExpectedIssueIDs)) { for i, issue := range issues { - assert.EqualValues(t, test.ExpectedIssueIDs[i], issue.ID) + assert.Equal(t, test.ExpectedIssueIDs[i], issue.ID) } } } @@ -234,10 +234,10 @@ func testInsertIssue(t *testing.T, title, content string, expectIndex int64) *is has, err := db.GetEngine(db.DefaultContext).ID(issue.ID).Get(&newIssue) assert.NoError(t, err) assert.True(t, has) - assert.EqualValues(t, issue.Title, newIssue.Title) - assert.EqualValues(t, issue.Content, newIssue.Content) + assert.Equal(t, issue.Title, newIssue.Title) + assert.Equal(t, issue.Content, newIssue.Content) if expectIndex > 0 { - assert.EqualValues(t, expectIndex, newIssue.Index) + assert.Equal(t, expectIndex, newIssue.Index) } }) return &newIssue @@ -271,7 +271,7 @@ func TestIssue_ResolveMentions(t *testing.T) { ids[i] = user.ID } sort.Slice(ids, func(i, j int) bool { return ids[i] < ids[j] }) - assert.EqualValues(t, expected, ids) + assert.Equal(t, expected, ids) } // Public repo, existing user @@ -392,28 +392,28 @@ func TestIssueLoadAttributes(t *testing.T) { for _, issue := range issueList { assert.NoError(t, issue.LoadAttributes(db.DefaultContext)) - assert.EqualValues(t, issue.RepoID, issue.Repo.ID) + assert.Equal(t, issue.RepoID, issue.Repo.ID) for _, label := range issue.Labels { - assert.EqualValues(t, issue.RepoID, label.RepoID) + assert.Equal(t, issue.RepoID, label.RepoID) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label.ID}) } if issue.PosterID > 0 { - assert.EqualValues(t, issue.PosterID, issue.Poster.ID) + assert.Equal(t, issue.PosterID, issue.Poster.ID) } if issue.AssigneeID > 0 { - assert.EqualValues(t, issue.AssigneeID, issue.Assignee.ID) + assert.Equal(t, issue.AssigneeID, issue.Assignee.ID) } if issue.MilestoneID > 0 { - assert.EqualValues(t, issue.MilestoneID, issue.Milestone.ID) + assert.Equal(t, issue.MilestoneID, issue.Milestone.ID) } if issue.IsPull { - assert.EqualValues(t, issue.ID, issue.PullRequest.IssueID) + assert.Equal(t, issue.ID, issue.PullRequest.IssueID) } for _, attachment := range issue.Attachments { - assert.EqualValues(t, issue.ID, attachment.IssueID) + assert.Equal(t, issue.ID, attachment.IssueID) } for _, comment := range issue.Comments { - assert.EqualValues(t, issue.ID, comment.IssueID) + assert.Equal(t, issue.ID, comment.IssueID) } if issue.ID == int64(1) { assert.Equal(t, int64(400), issue.TotalTrackedTime) diff --git a/models/issues/issue_update.go b/models/issues/issue_update.go index 7b3fe04aa5..746a59c6fd 100644 --- a/models/issues/issue_update.go +++ b/models/issues/issue_update.go @@ -5,6 +5,7 @@ package issues import ( "context" + "errors" "fmt" "strings" @@ -386,10 +387,10 @@ func NewIssueWithIndex(ctx context.Context, doer *user_model.User, opts NewIssue } if opts.Issue.Index <= 0 { - return fmt.Errorf("no issue index provided") + return errors.New("no issue index provided") } if opts.Issue.ID > 0 { - return fmt.Errorf("issue exist") + return errors.New("issue exist") } if _, err := e.Insert(opts.Issue); err != nil { diff --git a/models/issues/label_test.go b/models/issues/label_test.go index 185fa11bbc..226036d543 100644 --- a/models/issues/label_test.go +++ b/models/issues/label_test.go @@ -20,7 +20,7 @@ func TestLabel_CalOpenIssues(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) label := unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) label.CalOpenIssues() - assert.EqualValues(t, 2, label.NumOpenIssues) + assert.Equal(t, 2, label.NumOpenIssues) } func TestLabel_LoadSelectedLabelsAfterClick(t *testing.T) { @@ -154,7 +154,7 @@ func TestGetLabelsByRepoID(t *testing.T) { assert.NoError(t, err) assert.Len(t, labels, len(expectedIssueIDs)) for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) + assert.Equal(t, expectedIssueIDs[i], label.ID) } } testSuccess(1, "leastissues", []int64{2, 1}) @@ -221,7 +221,7 @@ func TestGetLabelsByOrgID(t *testing.T) { assert.NoError(t, err) assert.Len(t, labels, len(expectedIssueIDs)) for i, label := range labels { - assert.EqualValues(t, expectedIssueIDs[i], label.ID) + assert.Equal(t, expectedIssueIDs[i], label.ID) } } testSuccess(3, "leastissues", []int64{3, 4}) @@ -267,10 +267,10 @@ func TestUpdateLabel(t *testing.T) { label.Name = update.Name assert.NoError(t, issues_model.UpdateLabel(db.DefaultContext, update)) 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) - assert.EqualValues(t, label.Description, newLabel.Description) + assert.Equal(t, label.ID, newLabel.ID) + assert.Equal(t, label.Color, newLabel.Color) + assert.Equal(t, label.Name, newLabel.Name) + assert.Equal(t, label.Description, newLabel.Description) assert.EqualValues(t, 0, newLabel.ArchivedUnix) unittest.CheckConsistencyFor(t, &issues_model.Label{}, &repo_model.Repository{}) } @@ -313,7 +313,7 @@ func TestNewIssueLabel(t *testing.T) { Content: "1", }) label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) - assert.EqualValues(t, prevNumIssues+1, label.NumIssues) + assert.Equal(t, prevNumIssues+1, label.NumIssues) // re-add existing IssueLabel assert.NoError(t, issues_model.NewIssueLabel(db.DefaultContext, issue, label, doer)) @@ -366,11 +366,11 @@ func TestNewIssueLabels(t *testing.T) { }) unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issue.ID, LabelID: label1.ID}) label1 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 1}) - assert.EqualValues(t, 3, label1.NumIssues) - assert.EqualValues(t, 1, label1.NumClosedIssues) + assert.Equal(t, 3, label1.NumIssues) + assert.Equal(t, 1, label1.NumClosedIssues) label2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: 2}) - assert.EqualValues(t, 1, label2.NumIssues) - assert.EqualValues(t, 1, label2.NumClosedIssues) + assert.Equal(t, 1, label2.NumIssues) + assert.Equal(t, 1, label2.NumClosedIssues) // corner case: test empty slice assert.NoError(t, issues_model.NewIssueLabels(db.DefaultContext, issue, []*issues_model.Label{}, doer)) @@ -408,8 +408,8 @@ func TestDeleteIssueLabel(t *testing.T) { LabelID: labelID, }, `content=''`) label = unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ID: labelID}) - assert.EqualValues(t, expectedNumIssues, label.NumIssues) - assert.EqualValues(t, expectedNumClosedIssues, label.NumClosedIssues) + assert.Equal(t, expectedNumIssues, label.NumIssues) + assert.Equal(t, expectedNumClosedIssues, label.NumClosedIssues) } testSuccess(1, 1, 2) testSuccess(2, 5, 2) diff --git a/models/issues/milestone_test.go b/models/issues/milestone_test.go index 28cd0c028b..f73355c27d 100644 --- a/models/issues/milestone_test.go +++ b/models/issues/milestone_test.go @@ -69,7 +69,7 @@ func TestGetMilestonesByRepoID(t *testing.T) { assert.Len(t, milestones, n) for _, milestone := range milestones { - assert.EqualValues(t, repoID, milestone.RepoID) + assert.Equal(t, repoID, milestone.RepoID) } } test(1, api.StateOpen) @@ -327,7 +327,7 @@ func TestUpdateMilestone(t *testing.T) { milestone.Content = "newMilestoneContent" assert.NoError(t, issues_model.UpdateMilestone(db.DefaultContext, milestone, milestone.IsClosed)) milestone = unittest.AssertExistsAndLoadBean(t, &issues_model.Milestone{ID: 1}) - assert.EqualValues(t, "newMilestoneName", milestone.Name) + assert.Equal(t, "newMilestoneName", milestone.Name) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) } @@ -364,7 +364,7 @@ func TestMigrate_InsertMilestones(t *testing.T) { assert.NoError(t, err) unittest.AssertExistsAndLoadBean(t, ms) repoModified := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: repo.ID}) - assert.EqualValues(t, repo.NumMilestones+1, repoModified.NumMilestones) + assert.Equal(t, repo.NumMilestones+1, repoModified.NumMilestones) unittest.CheckConsistencyFor(t, &issues_model.Milestone{}) } diff --git a/models/issues/pull.go b/models/issues/pull.go index e3af00224d..016db9f75c 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -6,6 +6,7 @@ package issues import ( "context" + "errors" "fmt" "io" "regexp" @@ -732,7 +733,7 @@ func (pr *PullRequest) GetWorkInProgressPrefix(ctx context.Context) string { // UpdateCommitDivergence update Divergence of a pull request func (pr *PullRequest) UpdateCommitDivergence(ctx context.Context, ahead, behind int) error { if pr.ID == 0 { - return fmt.Errorf("pull ID is 0") + return errors.New("pull ID is 0") } pr.CommitsAhead = ahead pr.CommitsBehind = behind @@ -925,7 +926,7 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule, if strings.Contains(user, "/") { s := strings.Split(user, "/") if len(s) != 2 { - warnings = append(warnings, fmt.Sprintf("incorrect codeowner group: %s", user)) + warnings = append(warnings, "incorrect codeowner group: "+user) continue } orgName := s[0] @@ -933,12 +934,12 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule, org, err := org_model.GetOrgByName(ctx, orgName) if err != nil { - warnings = append(warnings, fmt.Sprintf("incorrect codeowner organization: %s", user)) + warnings = append(warnings, "incorrect codeowner organization: "+user) continue } teams, err := org.LoadTeams(ctx) if err != nil { - warnings = append(warnings, fmt.Sprintf("incorrect codeowner team: %s", user)) + warnings = append(warnings, "incorrect codeowner team: "+user) continue } @@ -950,7 +951,7 @@ func ParseCodeOwnersLine(ctx context.Context, tokens []string) (*CodeOwnerRule, } else { u, err := user_model.GetUserByName(ctx, user) if err != nil { - warnings = append(warnings, fmt.Sprintf("incorrect codeowner user: %s", user)) + warnings = append(warnings, "incorrect codeowner user: "+user) continue } rule.Users = append(rule.Users, u) diff --git a/models/issues/pull_list_test.go b/models/issues/pull_list_test.go index f5553e7885..eb2de006d6 100644 --- a/models/issues/pull_list_test.go +++ b/models/issues/pull_list_test.go @@ -40,7 +40,7 @@ func TestPullRequestList_LoadReviewCommentsCounts(t *testing.T) { assert.NoError(t, err) assert.Len(t, reviewComments, 2) for _, pr := range prs { - assert.EqualValues(t, 1, reviewComments[pr.IssueID]) + assert.Equal(t, 1, reviewComments[pr.IssueID]) } } diff --git a/models/issues/pull_test.go b/models/issues/pull_test.go index 090659864a..8e09030215 100644 --- a/models/issues/pull_test.go +++ b/models/issues/pull_test.go @@ -285,7 +285,7 @@ func TestDeleteOrphanedObjects(t *testing.T) { countAfter, err := db.GetEngine(db.DefaultContext).Count(&issues_model.PullRequest{}) assert.NoError(t, err) - assert.EqualValues(t, countBefore, countAfter) + assert.Equal(t, countBefore, countAfter) } func TestParseCodeOwnersLine(t *testing.T) { @@ -318,7 +318,7 @@ func TestGetApprovers(t *testing.T) { setting.Repository.PullRequest.DefaultMergeMessageOfficialApproversOnly = false approvers := pr.GetApprovers(db.DefaultContext) expected := "Reviewed-by: User Five \nReviewed-by: Org Six \n" - assert.EqualValues(t, expected, approvers) + assert.Equal(t, expected, approvers) } func TestGetPullRequestByMergedCommit(t *testing.T) { diff --git a/models/issues/review.go b/models/issues/review.go index 1c5c2ee30a..2667bdaa7b 100644 --- a/models/issues/review.go +++ b/models/issues/review.go @@ -5,6 +5,7 @@ package issues import ( "context" + "errors" "fmt" "slices" "strings" @@ -374,7 +375,7 @@ func CreateReview(ctx context.Context, opts CreateReviewOptions) (*Review, error review.Type = ReviewTypeRequest review.ReviewerTeamID = opts.ReviewerTeam.ID } else { - return nil, fmt.Errorf("provide either reviewer or reviewer team") + return nil, errors.New("provide either reviewer or reviewer team") } if _, err := sess.Insert(review); err != nil { @@ -933,7 +934,7 @@ func MarkConversation(ctx context.Context, comment *Comment, doer *user_model.Us // the PR writer , official reviewer and poster can do it func CanMarkConversation(ctx context.Context, issue *Issue, doer *user_model.User) (permResult bool, err error) { if doer == nil || issue == nil { - return false, fmt.Errorf("issue or doer is nil") + return false, errors.New("issue or doer is nil") } if err = issue.LoadRepo(ctx); err != nil { @@ -972,11 +973,11 @@ func DeleteReview(ctx context.Context, r *Review) error { defer committer.Close() if r.ID == 0 { - return fmt.Errorf("review is not allowed to be 0") + return errors.New("review is not allowed to be 0") } if r.Type == ReviewTypeRequest { - return fmt.Errorf("review request can not be deleted using this method") + return errors.New("review request can not be deleted using this method") } opts := FindCommentsOptions{ diff --git a/models/migrations/base/db.go b/models/migrations/base/db.go index eb1c44a79e..4ecc930f10 100644 --- a/models/migrations/base/db.go +++ b/models/migrations/base/db.go @@ -52,7 +52,7 @@ func RecreateTable(sess *xorm.Session, bean any) error { // TODO: This will not work if there are foreign keys tableName := sess.Engine().TableName(bean) - tempTableName := fmt.Sprintf("tmp_recreate__%s", tableName) + tempTableName := "tmp_recreate__" + tableName // We need to move the old table away and create a new one with the correct columns // We will need to do this in stages to prevent data loss @@ -82,7 +82,7 @@ func RecreateTable(sess *xorm.Session, bean any) error { } newTableColumns := table.Columns() if len(newTableColumns) == 0 { - return fmt.Errorf("no columns in new table") + return errors.New("no columns in new table") } hasID := false for _, column := range newTableColumns { @@ -552,11 +552,11 @@ func deleteDB() error { } defer db.Close() - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { return err } - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name); err != nil { return err } return nil @@ -568,11 +568,11 @@ func deleteDB() error { } defer db.Close() - if _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name); err != nil { return err } - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("CREATE DATABASE " + setting.Database.Name); err != nil { return err } db.Close() @@ -594,7 +594,7 @@ func deleteDB() error { if !schrows.Next() { // Create and setup a DB schema - _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)) + _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema) if err != nil { return err } diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index 6e631f98c7..6a60067782 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -6,6 +6,7 @@ package migrations import ( "context" + "errors" "fmt" "code.gitea.io/gitea/models/migrations/v1_10" @@ -424,7 +425,7 @@ func EnsureUpToDate(ctx context.Context, x *xorm.Engine) error { } if currentDB < 0 { - return fmt.Errorf("database has not been initialized") + return errors.New("database has not been initialized") } if minDBVersion > currentDB { diff --git a/models/migrations/migrations_test.go b/models/migrations/migrations_test.go index e66b015b3d..8649d116f5 100644 --- a/models/migrations/migrations_test.go +++ b/models/migrations/migrations_test.go @@ -22,7 +22,7 @@ func TestMigrations(t *testing.T) { assert.EqualValues(t, 71, migrationIDNumberToDBVersion(70)) - assert.EqualValues(t, []*migration{{idNumber: 70}, {idNumber: 71}}, getPendingMigrations(70, preparedMigrations)) - assert.EqualValues(t, []*migration{{idNumber: 71}}, getPendingMigrations(71, preparedMigrations)) - assert.EqualValues(t, []*migration{}, getPendingMigrations(72, preparedMigrations)) + assert.Equal(t, []*migration{{idNumber: 70}, {idNumber: 71}}, getPendingMigrations(70, preparedMigrations)) + assert.Equal(t, []*migration{{idNumber: 71}}, getPendingMigrations(71, preparedMigrations)) + assert.Equal(t, []*migration{}, getPendingMigrations(72, preparedMigrations)) } diff --git a/models/migrations/v1_13/v140.go b/models/migrations/v1_13/v140.go index 2d3337012d..f3719e16f6 100644 --- a/models/migrations/v1_13/v140.go +++ b/models/migrations/v1_13/v140.go @@ -46,7 +46,7 @@ func FixLanguageStatsToSaveSize(x *xorm.Engine) error { } // Delete language stats - if _, err := x.Exec(fmt.Sprintf("%s language_stat", truncExpr)); err != nil { + if _, err := x.Exec(truncExpr + " language_stat"); err != nil { return err } diff --git a/models/migrations/v1_13/v145.go b/models/migrations/v1_13/v145.go index 8acb29bf33..bb1f40baa7 100644 --- a/models/migrations/v1_13/v145.go +++ b/models/migrations/v1_13/v145.go @@ -42,7 +42,7 @@ func IncreaseLanguageField(x *xorm.Engine) error { switch { case setting.Database.Type.IsMySQL(): - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat MODIFY COLUMN language %s", sqlType)); err != nil { + if _, err := sess.Exec("ALTER TABLE language_stat MODIFY COLUMN language " + sqlType); err != nil { return err } case setting.Database.Type.IsMSSQL(): @@ -64,7 +64,7 @@ func IncreaseLanguageField(x *xorm.Engine) error { return fmt.Errorf("Drop table `language_stat` constraint `%s`: %w", constraint, err) } } - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language %s", sqlType)); err != nil { + if _, err := sess.Exec("ALTER TABLE language_stat ALTER COLUMN language " + sqlType); err != nil { return err } // Finally restore the constraint @@ -72,7 +72,7 @@ func IncreaseLanguageField(x *xorm.Engine) error { return err } case setting.Database.Type.IsPostgreSQL(): - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE language_stat ALTER COLUMN language TYPE %s", sqlType)); err != nil { + if _, err := sess.Exec("ALTER TABLE language_stat ALTER COLUMN language TYPE " + sqlType); err != nil { return err } } diff --git a/models/migrations/v1_13/v151.go b/models/migrations/v1_13/v151.go index 25af1d03ec..1865d58f04 100644 --- a/models/migrations/v1_13/v151.go +++ b/models/migrations/v1_13/v151.go @@ -5,6 +5,7 @@ package v1_13 //nolint import ( "context" + "errors" "fmt" "strings" @@ -113,7 +114,7 @@ func SetDefaultPasswordToArgon2(x *xorm.Engine) error { newTableColumns := table.Columns() if len(newTableColumns) == 0 { - return fmt.Errorf("no columns in new table") + return errors.New("no columns in new table") } hasID := false for _, column := range newTableColumns { diff --git a/models/migrations/v1_14/v158.go b/models/migrations/v1_14/v158.go index 1094d8abf7..a849ddf27e 100644 --- a/models/migrations/v1_14/v158.go +++ b/models/migrations/v1_14/v158.go @@ -4,7 +4,7 @@ package v1_14 //nolint import ( - "fmt" + "errors" "strconv" "code.gitea.io/gitea/modules/log" @@ -82,7 +82,7 @@ func UpdateCodeCommentReplies(x *xorm.Engine) error { sqlCmd = "SELECT TOP " + strconv.Itoa(batchSize) + " * FROM #temp_comments WHERE " + "(id NOT IN ( SELECT TOP " + strconv.Itoa(start) + " id FROM #temp_comments ORDER BY id )) ORDER BY id" default: - return fmt.Errorf("Unsupported database type") + return errors.New("Unsupported database type") } if err := sess.SQL(sqlCmd).Find(&comments); err != nil { diff --git a/models/migrations/v1_15/v181_test.go b/models/migrations/v1_15/v181_test.go index 1b075be7a0..7295aa4180 100644 --- a/models/migrations/v1_15/v181_test.go +++ b/models/migrations/v1_15/v181_test.go @@ -49,7 +49,7 @@ func Test_AddPrimaryEmail2EmailAddress(t *testing.T) { assert.NoError(t, err) assert.True(t, has) assert.True(t, emailAddress.IsPrimary) - assert.EqualValues(t, user.IsActive, emailAddress.IsActivated) - assert.EqualValues(t, user.ID, emailAddress.UID) + assert.Equal(t, user.IsActive, emailAddress.IsActivated) + assert.Equal(t, user.ID, emailAddress.UID) } } diff --git a/models/migrations/v1_16/v189_test.go b/models/migrations/v1_16/v189_test.go index 32ef821d27..2a73bfae03 100644 --- a/models/migrations/v1_16/v189_test.go +++ b/models/migrations/v1_16/v189_test.go @@ -75,8 +75,8 @@ func Test_UnwrapLDAPSourceCfg(t *testing.T) { return } - assert.EqualValues(t, expected, converted, "UnwrapLDAPSourceCfg failed for %d", source.ID) - assert.EqualValues(t, source.ID%2 == 0, source.IsActive, "UnwrapLDAPSourceCfg failed for %d", source.ID) + assert.Equal(t, expected, converted, "UnwrapLDAPSourceCfg failed for %d", source.ID) + assert.Equal(t, source.ID%2 == 0, source.IsActive, "UnwrapLDAPSourceCfg failed for %d", source.ID) } } } diff --git a/models/migrations/v1_16/v193_test.go b/models/migrations/v1_16/v193_test.go index b279967a2c..7f43846bc3 100644 --- a/models/migrations/v1_16/v193_test.go +++ b/models/migrations/v1_16/v193_test.go @@ -62,7 +62,7 @@ func Test_AddRepoIDForAttachment(t *testing.T) { has, err := x.ID(attach.IssueID).Get(&issue) assert.NoError(t, err) assert.True(t, has) - assert.EqualValues(t, attach.RepoID, issue.RepoID) + assert.Equal(t, attach.RepoID, issue.RepoID) } var releaseAttachments []*NewAttachment @@ -75,6 +75,6 @@ func Test_AddRepoIDForAttachment(t *testing.T) { has, err := x.ID(attach.ReleaseID).Get(&release) assert.NoError(t, err) assert.True(t, has) - assert.EqualValues(t, attach.RepoID, release.RepoID) + assert.Equal(t, attach.RepoID, release.RepoID) } } diff --git a/models/migrations/v1_16/v210_test.go b/models/migrations/v1_16/v210_test.go index d43fb03106..7917301c98 100644 --- a/models/migrations/v1_16/v210_test.go +++ b/models/migrations/v1_16/v210_test.go @@ -71,5 +71,5 @@ func Test_RemigrateU2FCredentials(t *testing.T) { return } - assert.EqualValues(t, expected, got) + assert.Equal(t, expected, got) } diff --git a/models/migrations/v1_17/v222.go b/models/migrations/v1_17/v222.go index 2ffb94eb1c..6c28f8102b 100644 --- a/models/migrations/v1_17/v222.go +++ b/models/migrations/v1_17/v222.go @@ -5,6 +5,7 @@ package v1_17 //nolint import ( "context" + "errors" "fmt" "code.gitea.io/gitea/models/migrations/base" @@ -29,7 +30,7 @@ func DropOldCredentialIDColumn(x *xorm.Engine) error { } if !credentialIDBytesExists { // looks like 221 hasn't properly run - return fmt.Errorf("webauthn_credential does not have a credential_id_bytes column... it is not safe to run this migration") + return errors.New("webauthn_credential does not have a credential_id_bytes column... it is not safe to run this migration") } // Create webauthnCredential table diff --git a/models/migrations/v1_19/v233_test.go b/models/migrations/v1_19/v233_test.go index 32c10ab0f4..5d445d5132 100644 --- a/models/migrations/v1_19/v233_test.go +++ b/models/migrations/v1_19/v233_test.go @@ -64,7 +64,7 @@ func Test_AddHeaderAuthorizationEncryptedColWebhook(t *testing.T) { assert.Equal(t, e.Meta, got[i].Meta) if e.HeaderAuthorization == "" { - assert.Equal(t, "", got[i].HeaderAuthorizationEncrypted) + assert.Empty(t, got[i].HeaderAuthorizationEncrypted) } else { cipherhex := got[i].HeaderAuthorizationEncrypted cleartext, err := secret.DecryptSecret(setting.SecretKey, cipherhex) diff --git a/models/migrations/v1_20/v245.go b/models/migrations/v1_20/v245.go index ab58d12880..5a195d2ccd 100644 --- a/models/migrations/v1_20/v245.go +++ b/models/migrations/v1_20/v245.go @@ -5,7 +5,6 @@ package v1_20 //nolint import ( "context" - "fmt" "code.gitea.io/gitea/models/migrations/base" "code.gitea.io/gitea/modules/setting" @@ -57,7 +56,7 @@ func RenameWebhookOrgToOwner(x *xorm.Engine) error { return err } sqlType := x.Dialect().SQLType(inferredTable.GetColumn("org_id")) - if _, err := sess.Exec(fmt.Sprintf("ALTER TABLE `webhook` CHANGE org_id owner_id %s", sqlType)); err != nil { + if _, err := sess.Exec("ALTER TABLE `webhook` CHANGE org_id owner_id " + sqlType); err != nil { return err } case setting.Database.Type.IsMSSQL(): diff --git a/models/migrations/v1_20/v259_test.go b/models/migrations/v1_20/v259_test.go index 5bc9a71391..a1aeb53d5d 100644 --- a/models/migrations/v1_20/v259_test.go +++ b/models/migrations/v1_20/v259_test.go @@ -96,7 +96,7 @@ func Test_ConvertScopedAccessTokens(t *testing.T) { tokens := make([]AccessToken, 0) err = x.Find(&tokens) assert.NoError(t, err) - assert.Equal(t, len(tests), len(tokens)) + assert.Len(t, tokens, len(tests)) // sort the tokens (insertion order by auto-incrementing primary key) sort.Slice(tokens, func(i, j int) bool { diff --git a/models/migrations/v1_21/v264.go b/models/migrations/v1_21/v264.go index e81a17ad6d..d737ef03b3 100644 --- a/models/migrations/v1_21/v264.go +++ b/models/migrations/v1_21/v264.go @@ -5,7 +5,7 @@ package v1_21 //nolint import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/timeutil" @@ -57,7 +57,7 @@ func AddBranchTable(x *xorm.Engine) error { if err != nil { return err } else if !has { - return fmt.Errorf("no admin user found") + return errors.New("no admin user found") } branches := make([]Branch, 0, 100) diff --git a/models/migrations/v1_22/v286_test.go b/models/migrations/v1_22/v286_test.go index 1f213ddb6e..4702e4c37c 100644 --- a/models/migrations/v1_22/v286_test.go +++ b/models/migrations/v1_22/v286_test.go @@ -108,11 +108,11 @@ func Test_RepositoryFormat(t *testing.T) { ok, err := x.ID(2).Get(repo) assert.NoError(t, err) assert.True(t, ok) - assert.EqualValues(t, "sha1", repo.ObjectFormatName) + assert.Equal(t, "sha1", repo.ObjectFormatName) repo = new(Repository) ok, err = x.ID(id).Get(repo) assert.NoError(t, err) assert.True(t, ok) - assert.EqualValues(t, "sha256", repo.ObjectFormatName) + assert.Equal(t, "sha256", repo.ObjectFormatName) } diff --git a/models/migrations/v1_22/v287_test.go b/models/migrations/v1_22/v287_test.go index 9c7b10947d..58c3152ac3 100644 --- a/models/migrations/v1_22/v287_test.go +++ b/models/migrations/v1_22/v287_test.go @@ -4,7 +4,7 @@ package v1_22 //nolint import ( - "fmt" + "strconv" "testing" "code.gitea.io/gitea/models/migrations/base" @@ -50,7 +50,7 @@ func Test_UpdateBadgeColName(t *testing.T) { for i, e := range oldBadges { got := got[i+1] // 1 is in the badge.yml assert.Equal(t, e.ID, got.ID) - assert.Equal(t, fmt.Sprintf("%d", e.ID), got.Slug) + assert.Equal(t, strconv.FormatInt(e.ID, 10), got.Slug) } // TODO: check if badges have been updated diff --git a/models/organization/org_list_test.go b/models/organization/org_list_test.go index 0f0f8a4bcd..e859d87c84 100644 --- a/models/organization/org_list_test.go +++ b/models/organization/org_list_test.go @@ -57,7 +57,7 @@ func TestGetUserOrgsList(t *testing.T) { if assert.Len(t, orgs, 1) { assert.EqualValues(t, 3, orgs[0].ID) // repo_id: 3 is in the team, 32 is public, 5 is private with no team - assert.EqualValues(t, 2, orgs[0].NumRepos) + assert.Equal(t, 2, orgs[0].NumRepos) } } diff --git a/models/organization/org_test.go b/models/organization/org_test.go index 6638abd8e0..666a6c44d4 100644 --- a/models/organization/org_test.go +++ b/models/organization/org_test.go @@ -135,7 +135,7 @@ func TestIsOrganizationOwner(t *testing.T) { test := func(orgID, userID int64, expected bool) { isOwner, err := organization.IsOrganizationOwner(db.DefaultContext, orgID, userID) assert.NoError(t, err) - assert.EqualValues(t, expected, isOwner) + assert.Equal(t, expected, isOwner) } test(3, 2, true) test(3, 3, false) @@ -149,7 +149,7 @@ func TestIsOrganizationMember(t *testing.T) { test := func(orgID, userID int64, expected bool) { isMember, err := organization.IsOrganizationMember(db.DefaultContext, orgID, userID) assert.NoError(t, err) - assert.EqualValues(t, expected, isMember) + assert.Equal(t, expected, isMember) } test(3, 2, true) test(3, 3, false) @@ -164,7 +164,7 @@ func TestIsPublicMembership(t *testing.T) { test := func(orgID, userID int64, expected bool) { isMember, err := organization.IsPublicMembership(db.DefaultContext, orgID, userID) assert.NoError(t, err) - assert.EqualValues(t, expected, isMember) + assert.Equal(t, expected, isMember) } test(3, 2, true) test(3, 3, false) @@ -237,7 +237,7 @@ func TestRestrictedUserOrgMembers(t *testing.T) { memberUIDs = append(memberUIDs, member.UID) } slices.Sort(memberUIDs) - assert.EqualValues(t, tc.expectedUIDs, memberUIDs) + assert.Equal(t, tc.expectedUIDs, memberUIDs) }) } } @@ -255,7 +255,7 @@ func TestGetOrgUsersByOrgID(t *testing.T) { sort.Slice(orgUsers, func(i, j int) bool { return orgUsers[i].ID < orgUsers[j].ID }) - assert.EqualValues(t, []*organization.OrgUser{{ + assert.Equal(t, []*organization.OrgUser{{ ID: 1, OrgID: 3, UID: 2, @@ -322,7 +322,7 @@ func TestAccessibleReposEnv_CountRepos(t *testing.T) { assert.NoError(t, err) count, err := env.CountRepos(db.DefaultContext) assert.NoError(t, err) - assert.EqualValues(t, expectedCount, count) + assert.Equal(t, expectedCount, count) } testSuccess(2, 3) testSuccess(4, 2) diff --git a/models/organization/org_user_test.go b/models/organization/org_user_test.go index c5110b2a34..689544430d 100644 --- a/models/organization/org_user_test.go +++ b/models/organization/org_user_test.go @@ -139,7 +139,7 @@ func TestAddOrgUser(t *testing.T) { unittest.AssertExistsAndLoadBean(t, ou) assert.Equal(t, isPublic, ou.IsPublic) org = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: orgID}) - assert.EqualValues(t, expectedNumMembers, org.NumMembers) + assert.Equal(t, expectedNumMembers, org.NumMembers) } setting.Service.DefaultOrgMemberVisible = false diff --git a/models/organization/team_test.go b/models/organization/team_test.go index deaabbfa2c..b0bf842584 100644 --- a/models/organization/team_test.go +++ b/models/organization/team_test.go @@ -77,7 +77,7 @@ func TestGetTeam(t *testing.T) { testSuccess := func(orgID int64, name string) { team, err := organization.GetTeam(db.DefaultContext, orgID, name) assert.NoError(t, err) - assert.EqualValues(t, orgID, team.OrgID) + assert.Equal(t, orgID, team.OrgID) assert.Equal(t, name, team.Name) } testSuccess(3, "Owners") @@ -95,7 +95,7 @@ func TestGetTeamByID(t *testing.T) { testSuccess := func(teamID int64) { team, err := organization.GetTeamByID(db.DefaultContext, teamID) assert.NoError(t, err) - assert.EqualValues(t, teamID, team.ID) + assert.Equal(t, teamID, team.ID) } testSuccess(1) testSuccess(2) @@ -163,7 +163,7 @@ func TestGetUserOrgTeams(t *testing.T) { teams, err := organization.GetUserOrgTeams(db.DefaultContext, orgID, userID) assert.NoError(t, err) for _, team := range teams { - assert.EqualValues(t, orgID, team.OrgID) + assert.Equal(t, orgID, team.OrgID) unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{TeamID: team.ID, UID: userID}) } } diff --git a/models/packages/descriptor.go b/models/packages/descriptor.go index d251fcc4a9..c97bd46c9e 100644 --- a/models/packages/descriptor.go +++ b/models/packages/descriptor.go @@ -197,7 +197,7 @@ func GetPackageDescriptor(ctx context.Context, pv *PackageVersion) (*PackageDesc case TypeVagrant: metadata = &vagrant.Metadata{} default: - panic(fmt.Sprintf("unknown package type: %s", string(p.Type))) + panic("unknown package type: " + string(p.Type)) } if metadata != nil { if err := json.Unmarshal([]byte(pv.MetadataJSON), &metadata); err != nil { diff --git a/models/packages/package.go b/models/packages/package.go index 8935dbaa1c..38d1cdcf66 100644 --- a/models/packages/package.go +++ b/models/packages/package.go @@ -127,7 +127,7 @@ func (pt Type) Name() string { case TypeVagrant: return "Vagrant" } - panic(fmt.Sprintf("unknown package type: %s", string(pt))) + panic("unknown package type: " + string(pt)) } // SVGName gets the name of the package type svg image @@ -178,7 +178,7 @@ func (pt Type) SVGName() string { case TypeVagrant: return "gitea-vagrant" } - panic(fmt.Sprintf("unknown package type: %s", string(pt))) + panic("unknown package type: " + string(pt)) } // Package represents a package diff --git a/models/project/column.go b/models/project/column.go index 77ff5ef83e..9b9d874997 100644 --- a/models/project/column.go +++ b/models/project/column.go @@ -147,7 +147,7 @@ func NewColumn(ctx context.Context, column *Column) error { return err } if res.ColumnCount >= maxProjectColumns { - return fmt.Errorf("NewBoard: maximum number of columns reached") + return errors.New("NewBoard: maximum number of columns reached") } column.Sorting = int8(util.Iif(res.ColumnCount > 0, res.MaxSorting+1, 0)) _, err := db.GetEngine(ctx).Insert(column) @@ -172,7 +172,7 @@ func deleteColumnByID(ctx context.Context, columnID int64) error { } if column.Default { - return fmt.Errorf("deleteColumnByID: cannot delete default column") + return errors.New("deleteColumnByID: cannot delete default column") } // move all issues to the default column diff --git a/models/project/column_test.go b/models/project/column_test.go index 66db23a3e4..5b93e7760f 100644 --- a/models/project/column_test.go +++ b/models/project/column_test.go @@ -97,9 +97,9 @@ func Test_MoveColumnsOnProject(t *testing.T) { columnsAfter, err := project1.GetColumns(db.DefaultContext) assert.NoError(t, err) assert.Len(t, columnsAfter, 3) - assert.EqualValues(t, columns[1].ID, columnsAfter[0].ID) - assert.EqualValues(t, columns[2].ID, columnsAfter[1].ID) - assert.EqualValues(t, columns[0].ID, columnsAfter[2].ID) + assert.Equal(t, columns[1].ID, columnsAfter[0].ID) + assert.Equal(t, columns[2].ID, columnsAfter[1].ID) + assert.Equal(t, columns[0].ID, columnsAfter[2].ID) } func Test_NewColumn(t *testing.T) { diff --git a/models/project/issue.go b/models/project/issue.go index 98eed2a213..47d1537ec7 100644 --- a/models/project/issue.go +++ b/models/project/issue.go @@ -5,7 +5,7 @@ package project import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/util" @@ -35,7 +35,7 @@ func deleteProjectIssuesByProjectID(ctx context.Context, projectID int64) error func (c *Column) moveIssuesToAnotherColumn(ctx context.Context, newColumn *Column) error { if c.ProjectID != newColumn.ProjectID { - return fmt.Errorf("columns have to be in the same project") + return errors.New("columns have to be in the same project") } if c.ID == newColumn.ID { diff --git a/models/project/project_test.go b/models/project/project_test.go index dd421b4659..c2e924e8ae 100644 --- a/models/project/project_test.go +++ b/models/project/project_test.go @@ -113,10 +113,10 @@ func TestProjectsSort(t *testing.T) { OrderBy: GetSearchOrderByBySortType(tt.sortType), }) assert.NoError(t, err) - assert.EqualValues(t, int64(6), count) + assert.Equal(t, int64(6), count) if assert.Len(t, projects, 6) { for i := range projects { - assert.EqualValues(t, tt.wants[i], projects[i].ID) + assert.Equal(t, tt.wants[i], projects[i].ID) } } } diff --git a/models/renderhelper/repo_comment.go b/models/renderhelper/repo_comment.go index 6bd5e91ad1..7c40eded44 100644 --- a/models/renderhelper/repo_comment.go +++ b/models/renderhelper/repo_comment.go @@ -28,14 +28,14 @@ func (r *RepoComment) IsCommitIDExisting(commitID string) bool { return r.commitChecker.IsCommitIDExisting(commitID) } -func (r *RepoComment) ResolveLink(link string, likeType markup.LinkType) (finalLink string) { - switch likeType { - case markup.LinkTypeApp: - finalLink = r.ctx.ResolveLinkApp(link) +func (r *RepoComment) ResolveLink(link, preferLinkType string) string { + linkType, link := markup.ParseRenderedLink(link, preferLinkType) + switch linkType { + case markup.LinkTypeRoot: + return r.ctx.ResolveLinkRoot(link) default: - finalLink = r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link) + return r.ctx.ResolveLinkRelative(r.repoLink, r.opts.CurrentRefPath, link) } - return finalLink } var _ markup.RenderHelper = (*RepoComment)(nil) @@ -56,7 +56,7 @@ func NewRenderContextRepoComment(ctx context.Context, repo *repo_model.Repositor if repo != nil { helper.repoLink = repo.Link() helper.commitChecker = newCommitChecker(ctx, repo) - rctx = rctx.WithMetas(repo.ComposeMetas(ctx)) + rctx = rctx.WithMetas(repo.ComposeCommentMetas(ctx)) } else { // this is almost dead code, only to pass the incorrect tests helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName) @@ -64,7 +64,7 @@ func NewRenderContextRepoComment(ctx context.Context, repo *repo_model.Repositor "user": helper.opts.DeprecatedOwnerName, "repo": helper.opts.DeprecatedRepoName, - "markdownLineBreakStyle": "comment", + "markdownNewLineHardBreak": "true", "markupAllowShortIssuePattern": "true", }) } diff --git a/models/renderhelper/repo_file.go b/models/renderhelper/repo_file.go index 794828c617..e0375ed280 100644 --- a/models/renderhelper/repo_file.go +++ b/models/renderhelper/repo_file.go @@ -29,17 +29,17 @@ func (r *RepoFile) IsCommitIDExisting(commitID string) bool { return r.commitChecker.IsCommitIDExisting(commitID) } -func (r *RepoFile) ResolveLink(link string, likeType markup.LinkType) string { - finalLink := link - switch likeType { - case markup.LinkTypeApp: - finalLink = r.ctx.ResolveLinkApp(link) - case markup.LinkTypeDefault: - finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link) +func (r *RepoFile) ResolveLink(link, preferLinkType string) (finalLink string) { + linkType, link := markup.ParseRenderedLink(link, preferLinkType) + switch linkType { + case markup.LinkTypeRoot: + finalLink = r.ctx.ResolveLinkRoot(link) case markup.LinkTypeRaw: finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "raw", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link) case markup.LinkTypeMedia: finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "media", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link) + default: + finalLink = r.ctx.ResolveLinkRelative(path.Join(r.repoLink, "src", r.opts.CurrentRefPath), r.opts.CurrentTreePath, link) } return finalLink } @@ -61,15 +61,13 @@ func NewRenderContextRepoFile(ctx context.Context, repo *repo_model.Repository, if repo != nil { helper.repoLink = repo.Link() helper.commitChecker = newCommitChecker(ctx, repo) - rctx = rctx.WithMetas(repo.ComposeDocumentMetas(ctx)) + rctx = rctx.WithMetas(repo.ComposeRepoFileMetas(ctx)) } else { // this is almost dead code, only to pass the incorrect tests helper.repoLink = fmt.Sprintf("%s/%s", helper.opts.DeprecatedOwnerName, helper.opts.DeprecatedRepoName) rctx = rctx.WithMetas(map[string]string{ "user": helper.opts.DeprecatedOwnerName, "repo": helper.opts.DeprecatedRepoName, - - "markdownLineBreakStyle": "document", }) } rctx = rctx.WithHelper(helper) diff --git a/models/renderhelper/repo_file_test.go b/models/renderhelper/repo_file_test.go index 29cb45f6f7..3b48efba3a 100644 --- a/models/renderhelper/repo_file_test.go +++ b/models/renderhelper/repo_file_test.go @@ -48,8 +48,8 @@ func TestRepoFile(t *testing.T) { assert.Equal(t, `/test ./test - - + +
/test ./test - -
/test -
https://google.com/ -The Image Desc
65f1bf27bc3bf70f64657658635e66094edbcb4d #1 -@user2
/test ./test diff --git a/models/repo/attachment.go b/models/repo/attachment.go index fa4f6c47e6..835bee5402 100644 --- a/models/repo/attachment.go +++ b/models/repo/attachment.go @@ -224,7 +224,7 @@ func DeleteAttachmentsByComment(ctx context.Context, commentID int64, remove boo // UpdateAttachmentByUUID Updates attachment via uuid func UpdateAttachmentByUUID(ctx context.Context, attach *Attachment, cols ...string) error { if attach.UUID == "" { - return fmt.Errorf("attachment uuid should be not blank") + return errors.New("attachment uuid should be not blank") } _, err := db.GetEngine(ctx).Where("uuid=?", attach.UUID).Cols(cols...).Update(attach) return err diff --git a/models/repo/avatar.go b/models/repo/avatar.go index ccfac12cad..eff64bd239 100644 --- a/models/repo/avatar.go +++ b/models/repo/avatar.go @@ -9,6 +9,7 @@ import ( "image/png" "io" "net/url" + "strconv" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/avatar" @@ -37,7 +38,7 @@ func (repo *Repository) RelAvatarLink(ctx context.Context) string { // generateRandomAvatar generates a random avatar for repository. func generateRandomAvatar(ctx context.Context, repo *Repository) error { - idToString := fmt.Sprintf("%d", repo.ID) + idToString := strconv.FormatInt(repo.ID, 10) seed := idToString img, err := avatar.RandomImage([]byte(seed)) diff --git a/models/repo/collaboration_test.go b/models/repo/collaboration_test.go index 639050f5fd..7b07dbffdf 100644 --- a/models/repo/collaboration_test.go +++ b/models/repo/collaboration_test.go @@ -25,8 +25,8 @@ func TestRepository_GetCollaborators(t *testing.T) { assert.NoError(t, err) assert.Len(t, collaborators, int(expectedLen)) for _, collaborator := range collaborators { - assert.EqualValues(t, collaborator.User.ID, collaborator.Collaboration.UserID) - assert.EqualValues(t, repoID, collaborator.Collaboration.RepoID) + assert.Equal(t, collaborator.User.ID, collaborator.Collaboration.UserID) + assert.Equal(t, repoID, collaborator.Collaboration.RepoID) } } test(1) @@ -51,7 +51,7 @@ func TestRepository_GetCollaborators(t *testing.T) { assert.NoError(t, err) assert.Len(t, collaborators2, 1) - assert.NotEqualValues(t, collaborators1[0].ID, collaborators2[0].ID) + assert.NotEqual(t, collaborators1[0].ID, collaborators2[0].ID) } func TestRepository_IsCollaborator(t *testing.T) { @@ -76,10 +76,10 @@ func TestRepository_ChangeCollaborationAccessMode(t *testing.T) { assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin)) collaboration := unittest.AssertExistsAndLoadBean(t, &repo_model.Collaboration{RepoID: repo.ID, UserID: 4}) - assert.EqualValues(t, perm.AccessModeAdmin, collaboration.Mode) + assert.Equal(t, perm.AccessModeAdmin, collaboration.Mode) access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: repo.ID}) - assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) + assert.Equal(t, perm.AccessModeAdmin, access.Mode) assert.NoError(t, repo_model.ChangeCollaborationAccessMode(db.DefaultContext, repo, 4, perm.AccessModeAdmin)) diff --git a/models/repo/repo.go b/models/repo/repo.go index 515c57916c..2977dfb9f1 100644 --- a/models/repo/repo.go +++ b/models/repo/repo.go @@ -5,6 +5,7 @@ package repo import ( "context" + "errors" "fmt" "html/template" "maps" @@ -59,7 +60,7 @@ type ErrRepoIsArchived struct { } func (err ErrRepoIsArchived) Error() string { - return fmt.Sprintf("%s is archived", err.Repo.LogString()) + return err.Repo.LogString() + " is archived" } type globalVarsStruct struct { @@ -511,15 +512,15 @@ func (repo *Repository) composeCommonMetas(ctx context.Context) map[string]strin "repo": repo.Name, } - unit, err := repo.GetUnit(ctx, unit.TypeExternalTracker) + unitExternalTracker, err := repo.GetUnit(ctx, unit.TypeExternalTracker) if err == nil { - metas["format"] = unit.ExternalTrackerConfig().ExternalTrackerFormat - switch unit.ExternalTrackerConfig().ExternalTrackerStyle { + metas["format"] = unitExternalTracker.ExternalTrackerConfig().ExternalTrackerFormat + switch unitExternalTracker.ExternalTrackerConfig().ExternalTrackerStyle { case markup.IssueNameStyleAlphanumeric: metas["style"] = markup.IssueNameStyleAlphanumeric case markup.IssueNameStyleRegexp: metas["style"] = markup.IssueNameStyleRegexp - metas["regexp"] = unit.ExternalTrackerConfig().ExternalTrackerRegexpPattern + metas["regexp"] = unitExternalTracker.ExternalTrackerConfig().ExternalTrackerRegexpPattern default: metas["style"] = markup.IssueNameStyleNumeric } @@ -543,11 +544,11 @@ func (repo *Repository) composeCommonMetas(ctx context.Context) map[string]strin return repo.commonRenderingMetas } -// ComposeMetas composes a map of metas for properly rendering comments or comment-like contents (commit message) -func (repo *Repository) ComposeMetas(ctx context.Context) map[string]string { +// ComposeCommentMetas composes a map of metas for properly rendering comments or comment-like contents (commit message) +func (repo *Repository) ComposeCommentMetas(ctx context.Context) map[string]string { metas := maps.Clone(repo.composeCommonMetas(ctx)) - metas["markdownLineBreakStyle"] = "comment" - metas["markupAllowShortIssuePattern"] = "true" + metas["markdownNewLineHardBreak"] = strconv.FormatBool(setting.Markdown.RenderOptionsComment.NewLineHardBreak) + metas["markupAllowShortIssuePattern"] = strconv.FormatBool(setting.Markdown.RenderOptionsComment.ShortIssuePattern) return metas } @@ -555,16 +556,17 @@ func (repo *Repository) ComposeMetas(ctx context.Context) map[string]string { func (repo *Repository) ComposeWikiMetas(ctx context.Context) map[string]string { // does wiki need the "teams" and "org" from common metas? metas := maps.Clone(repo.composeCommonMetas(ctx)) - metas["markdownLineBreakStyle"] = "document" - metas["markupAllowShortIssuePattern"] = "true" + metas["markdownNewLineHardBreak"] = strconv.FormatBool(setting.Markdown.RenderOptionsWiki.NewLineHardBreak) + metas["markupAllowShortIssuePattern"] = strconv.FormatBool(setting.Markdown.RenderOptionsWiki.ShortIssuePattern) return metas } -// ComposeDocumentMetas composes a map of metas for properly rendering documents (repo files) -func (repo *Repository) ComposeDocumentMetas(ctx context.Context) map[string]string { +// ComposeRepoFileMetas composes a map of metas for properly rendering documents (repo files) +func (repo *Repository) ComposeRepoFileMetas(ctx context.Context) map[string]string { // does document(file) need the "teams" and "org" from common metas? metas := maps.Clone(repo.composeCommonMetas(ctx)) - metas["markdownLineBreakStyle"] = "document" + metas["markdownNewLineHardBreak"] = strconv.FormatBool(setting.Markdown.RenderOptionsRepoFile.NewLineHardBreak) + metas["markupAllowShortIssuePattern"] = strconv.FormatBool(setting.Markdown.RenderOptionsRepoFile.ShortIssuePattern) return metas } @@ -820,7 +822,7 @@ func GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*Repo func GetRepositoryByURL(ctx context.Context, repoURL string) (*Repository, error) { ret, err := giturl.ParseRepositoryURL(ctx, repoURL) if err != nil || ret.OwnerName == "" { - return nil, fmt.Errorf("unknown or malformed repository URL") + return nil, errors.New("unknown or malformed repository URL") } return GetRepositoryByOwnerAndName(ctx, ret.OwnerName, ret.RepoName) } diff --git a/models/repo/repo_test.go b/models/repo/repo_test.go index dffbd18261..b2604ab575 100644 --- a/models/repo/repo_test.go +++ b/models/repo/repo_test.go @@ -86,7 +86,7 @@ func TestMetas(t *testing.T) { repo.Units = nil - metas := repo.ComposeMetas(db.DefaultContext) + metas := repo.ComposeCommentMetas(db.DefaultContext) assert.Equal(t, "testRepo", metas["repo"]) assert.Equal(t, "testOwner", metas["user"]) @@ -100,7 +100,7 @@ func TestMetas(t *testing.T) { testSuccess := func(expectedStyle string) { repo.Units = []*RepoUnit{&externalTracker} repo.commonRenderingMetas = nil - metas := repo.ComposeMetas(db.DefaultContext) + metas := repo.ComposeCommentMetas(db.DefaultContext) assert.Equal(t, expectedStyle, metas["style"]) assert.Equal(t, "testRepo", metas["repo"]) assert.Equal(t, "testOwner", metas["user"]) @@ -121,7 +121,7 @@ func TestMetas(t *testing.T) { repo, err := GetRepositoryByID(db.DefaultContext, 3) assert.NoError(t, err) - metas = repo.ComposeMetas(db.DefaultContext) + metas = repo.ComposeCommentMetas(db.DefaultContext) assert.Contains(t, metas, "org") assert.Contains(t, metas, "teams") assert.Equal(t, "org3", metas["org"]) diff --git a/models/repo/repo_unit.go b/models/repo/repo_unit.go index e83a3dc8c2..8a7dbfe340 100644 --- a/models/repo/repo_unit.go +++ b/models/repo/repo_unit.go @@ -5,7 +5,6 @@ package repo import ( "context" - "fmt" "slices" "strings" @@ -33,7 +32,7 @@ func IsErrUnitTypeNotExist(err error) bool { } func (err ErrUnitTypeNotExist) Error() string { - return fmt.Sprintf("Unit type does not exist: %s", err.UT.LogString()) + return "Unit type does not exist: " + err.UT.LogString() } func (err ErrUnitTypeNotExist) Unwrap() error { diff --git a/models/repo/repo_unit_test.go b/models/repo/repo_unit_test.go index a760594013..56dda5672d 100644 --- a/models/repo/repo_unit_test.go +++ b/models/repo/repo_unit_test.go @@ -12,19 +12,19 @@ import ( func TestActionsConfig(t *testing.T) { cfg := &ActionsConfig{} cfg.DisableWorkflow("test1.yaml") - assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) + assert.Equal(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) cfg.DisableWorkflow("test1.yaml") - assert.EqualValues(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) + assert.Equal(t, []string{"test1.yaml"}, cfg.DisabledWorkflows) cfg.EnableWorkflow("test1.yaml") - assert.EqualValues(t, []string{}, cfg.DisabledWorkflows) + assert.Equal(t, []string{}, cfg.DisabledWorkflows) cfg.EnableWorkflow("test1.yaml") - assert.EqualValues(t, []string{}, cfg.DisabledWorkflows) + assert.Equal(t, []string{}, cfg.DisabledWorkflows) cfg.DisableWorkflow("test1.yaml") cfg.DisableWorkflow("test2.yaml") cfg.DisableWorkflow("test3.yaml") - assert.EqualValues(t, "test1.yaml,test2.yaml,test3.yaml", cfg.ToString()) + assert.Equal(t, "test1.yaml,test2.yaml,test3.yaml", cfg.ToString()) } diff --git a/models/repo/topic_test.go b/models/repo/topic_test.go index 1600896b6e..b6a7aed7b1 100644 --- a/models/repo/topic_test.go +++ b/models/repo/topic_test.go @@ -53,7 +53,7 @@ func TestAddTopic(t *testing.T) { totalNrOfTopics++ topic, err := repo_model.GetTopicByName(db.DefaultContext, "gitea") assert.NoError(t, err) - assert.EqualValues(t, 1, topic.RepoCount) + assert.Equal(t, 1, topic.RepoCount) topics, err = db.Find[repo_model.Topic](db.DefaultContext, &repo_model.FindTopicOptions{}) assert.NoError(t, err) diff --git a/models/repo/watch_test.go b/models/repo/watch_test.go index c39ef607e8..7ed72386c9 100644 --- a/models/repo/watch_test.go +++ b/models/repo/watch_test.go @@ -36,7 +36,7 @@ func TestGetWatchers(t *testing.T) { // One watchers are inactive, thus minus 1 assert.Len(t, watches, repo.NumWatches-1) for _, watch := range watches { - assert.EqualValues(t, repo.ID, watch.RepoID) + assert.Equal(t, repo.ID, watch.RepoID) } watches, err = repo_model.GetWatchers(db.DefaultContext, unittest.NonexistentID) diff --git a/models/repo/wiki.go b/models/repo/wiki.go index 4239a815b2..832e15ae0d 100644 --- a/models/repo/wiki.go +++ b/models/repo/wiki.go @@ -46,7 +46,7 @@ func IsErrWikiReservedName(err error) bool { } func (err ErrWikiReservedName) Error() string { - return fmt.Sprintf("wiki title is reserved: %s", err.Title) + return "wiki title is reserved: " + err.Title } func (err ErrWikiReservedName) Unwrap() error { @@ -65,7 +65,7 @@ func IsErrWikiInvalidFileName(err error) bool { } func (err ErrWikiInvalidFileName) Error() string { - return fmt.Sprintf("Invalid wiki filename: %s", err.FileName) + return "Invalid wiki filename: " + err.FileName } func (err ErrWikiInvalidFileName) Unwrap() error { diff --git a/models/repo_test.go b/models/repo_test.go index bcf62237f0..b6c53fd197 100644 --- a/models/repo_test.go +++ b/models/repo_test.go @@ -29,10 +29,10 @@ func Test_repoStatsCorrectIssueNumComments(t *testing.T) { issue2 := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) assert.NotNil(t, issue2) - assert.EqualValues(t, 0, issue2.NumComments) // the fixture data is wrong, but we don't fix it here + assert.Equal(t, 0, issue2.NumComments) // the fixture data is wrong, but we don't fix it here assert.NoError(t, repoStatsCorrectIssueNumComments(db.DefaultContext, 2)) // reload the issue issue2 = unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 2}) - assert.EqualValues(t, 1, issue2.NumComments) + assert.Equal(t, 1, issue2.NumComments) } diff --git a/models/system/setting_test.go b/models/system/setting_test.go index 8f04412fb4..7e7e0c8fca 100644 --- a/models/system/setting_test.go +++ b/models/system/setting_test.go @@ -21,24 +21,24 @@ func TestSettings(t *testing.T) { rev, settings, err := system.GetAllSettings(db.DefaultContext) assert.NoError(t, err) - assert.EqualValues(t, 1, rev) + assert.Equal(t, 1, rev) assert.Len(t, settings, 1) // there is only one "revision" key err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "true"}) assert.NoError(t, err) rev, settings, err = system.GetAllSettings(db.DefaultContext) assert.NoError(t, err) - assert.EqualValues(t, 2, rev) + assert.Equal(t, 2, rev) assert.Len(t, settings, 2) - assert.EqualValues(t, "true", settings[keyName]) + assert.Equal(t, "true", settings[keyName]) err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) assert.NoError(t, err) rev, settings, err = system.GetAllSettings(db.DefaultContext) assert.NoError(t, err) - assert.EqualValues(t, 3, rev) + assert.Equal(t, 3, rev) assert.Len(t, settings, 2) - assert.EqualValues(t, "false", settings[keyName]) + assert.Equal(t, "false", settings[keyName]) // setting the same value should not trigger DuplicateKey error, and the "version" should be increased err = system.SetSettings(db.DefaultContext, map[string]string{keyName: "false"}) @@ -47,5 +47,5 @@ func TestSettings(t *testing.T) { rev, settings, err = system.GetAllSettings(db.DefaultContext) assert.NoError(t, err) assert.Len(t, settings, 2) - assert.EqualValues(t, 4, rev) + assert.Equal(t, 4, rev) } diff --git a/models/unittest/consistency.go b/models/unittest/consistency.go index 71839001be..364afb5c52 100644 --- a/models/unittest/consistency.go +++ b/models/unittest/consistency.go @@ -11,6 +11,7 @@ import ( "code.gitea.io/gitea/models/db" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "xorm.io/builder" ) @@ -24,7 +25,7 @@ const ( var consistencyCheckMap = make(map[string]func(t assert.TestingT, bean any)) // CheckConsistencyFor test that all matching database entries are consistent -func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) { +func CheckConsistencyFor(t require.TestingT, beansToCheck ...any) { for _, bean := range beansToCheck { sliceType := reflect.SliceOf(reflect.TypeOf(bean)) sliceValue := reflect.MakeSlice(sliceType, 0, 10) @@ -42,13 +43,11 @@ func CheckConsistencyFor(t assert.TestingT, beansToCheck ...any) { } } -func checkForConsistency(t assert.TestingT, bean any) { +func checkForConsistency(t require.TestingT, bean any) { tb, err := db.TableInfo(bean) assert.NoError(t, err) f := consistencyCheckMap[tb.Name] - if f == nil { - assert.FailNow(t, "unknown bean type: %#v", bean) - } + require.NotNil(t, f, "unknown bean type: %#v", bean) f(t, bean) } @@ -71,8 +70,8 @@ func init() { AssertCountByCond(t, "follow", builder.Eq{"user_id": user.int("ID")}, user.int("NumFollowing")) AssertCountByCond(t, "follow", builder.Eq{"follow_id": user.int("ID")}, user.int("NumFollowers")) if user.int("Type") != modelsUserTypeOrganization { - assert.EqualValues(t, 0, user.int("NumMembers"), "Unexpected number of members for user id: %d", user.int("ID")) - assert.EqualValues(t, 0, user.int("NumTeams"), "Unexpected number of teams for user id: %d", user.int("ID")) + assert.Equal(t, 0, user.int("NumMembers"), "Unexpected number of members for user id: %d", user.int("ID")) + assert.Equal(t, 0, user.int("NumTeams"), "Unexpected number of teams for user id: %d", user.int("ID")) } } @@ -119,7 +118,7 @@ func init() { assert.EqualValues(t, issue.int("NumComments"), actual, "Unexpected number of comments for issue id: %d", issue.int("ID")) if issue.bool("IsPull") { prRow := AssertExistsAndLoadMap(t, "pull_request", builder.Eq{"issue_id": issue.int("ID")}) - assert.EqualValues(t, parseInt(prRow["index"]), issue.int("Index"), "Unexpected index for issue id: %d", issue.int("ID")) + assert.Equal(t, parseInt(prRow["index"]), issue.int("Index"), "Unexpected index for issue id: %d", issue.int("ID")) } } @@ -127,7 +126,7 @@ func init() { pr := reflectionWrap(bean) issueRow := AssertExistsAndLoadMap(t, "issue", builder.Eq{"id": pr.int("IssueID")}) assert.True(t, parseBool(issueRow["is_pull"])) - assert.EqualValues(t, parseInt(issueRow["index"]), pr.int("Index"), "Unexpected index for pull request id: %d", pr.int("ID")) + assert.Equal(t, parseInt(issueRow["index"]), pr.int("Index"), "Unexpected index for pull request id: %d", pr.int("ID")) } checkForMilestoneConsistency := func(t assert.TestingT, bean any) { diff --git a/models/unittest/fixtures_loader.go b/models/unittest/fixtures_loader.go index 674f5cbe54..0560da8349 100644 --- a/models/unittest/fixtures_loader.go +++ b/models/unittest/fixtures_loader.go @@ -120,7 +120,7 @@ func (f *fixturesLoaderInternal) loadFixtures(tx *sql.Tx, fixture *FixtureItem) } } - _, err = tx.Exec(fmt.Sprintf("DELETE FROM %s", fixture.tableNameQuoted)) // sqlite3 doesn't support truncate + _, err = tx.Exec("DELETE FROM " + fixture.tableNameQuoted) // sqlite3 doesn't support truncate if err != nil { return err } diff --git a/models/unittest/unit_tests.go b/models/unittest/unit_tests.go index 1c5595aef8..4a4cec40ae 100644 --- a/models/unittest/unit_tests.go +++ b/models/unittest/unit_tests.go @@ -153,9 +153,9 @@ func DumpQueryResult(t require.TestingT, sqlOrBean any, sqlArgs ...any) { goDB := x.DB().DB sql, ok := sqlOrBean.(string) if !ok { - sql = fmt.Sprintf("SELECT * FROM %s", db.TableName(sqlOrBean)) + sql = "SELECT * FROM " + db.TableName(sqlOrBean) } else if !strings.Contains(sql, " ") { - sql = fmt.Sprintf("SELECT * FROM %s", sql) + sql = "SELECT * FROM " + sql } rows, err := goDB.Query(sql, sqlArgs...) require.NoError(t, err) diff --git a/models/user/avatar.go b/models/user/avatar.go index 2a41b99129..3d9fc4452f 100644 --- a/models/user/avatar.go +++ b/models/user/avatar.go @@ -61,7 +61,9 @@ func GenerateRandomAvatar(ctx context.Context, u *User) error { // AvatarLinkWithSize returns a link to the user's avatar with size. size <= 0 means default size func (u *User) AvatarLinkWithSize(ctx context.Context, size int) string { - if u.IsGhost() || u.IsGiteaActions() { + // ghost user was deleted, Gitea actions is a bot user, 0 means the user should be a virtual user + // which comes from git configure information + if u.IsGhost() || u.IsGiteaActions() || u.ID <= 0 { return avatars.DefaultAvatarLink() } diff --git a/models/user/email_address_test.go b/models/user/email_address_test.go index d72d873de2..0e52950cfd 100644 --- a/models/user/email_address_test.go +++ b/models/user/email_address_test.go @@ -205,7 +205,7 @@ func TestEmailAddressValidate(t *testing.T) { } for kase, err := range kases { t.Run(kase, func(t *testing.T) { - assert.EqualValues(t, err, user_model.ValidateEmail(kase)) + assert.Equal(t, err, user_model.ValidateEmail(kase)) }) } } diff --git a/models/user/setting.go b/models/user/setting.go index b4af0e5ccd..c65afae76c 100644 --- a/models/user/setting.go +++ b/models/user/setting.go @@ -5,6 +5,7 @@ package user import ( "context" + "errors" "fmt" "strings" @@ -114,10 +115,10 @@ func GetUserAllSettings(ctx context.Context, uid int64) (map[string]*Setting, er func validateUserSettingKey(key string) error { if len(key) == 0 { - return fmt.Errorf("setting key must be set") + return errors.New("setting key must be set") } if strings.ToLower(key) != key { - return fmt.Errorf("setting key should be lowercase") + return errors.New("setting key should be lowercase") } return nil } diff --git a/models/user/setting_test.go b/models/user/setting_test.go index c607d9fd00..3c199013f3 100644 --- a/models/user/setting_test.go +++ b/models/user/setting_test.go @@ -30,15 +30,15 @@ func TestSettings(t *testing.T) { settings, err := user_model.GetSettings(db.DefaultContext, 99, []string{keyName}) assert.NoError(t, err) assert.Len(t, settings, 1) - assert.EqualValues(t, newSetting.SettingValue, settings[keyName].SettingValue) + assert.Equal(t, newSetting.SettingValue, settings[keyName].SettingValue) settingValue, err := user_model.GetUserSetting(db.DefaultContext, 99, keyName) assert.NoError(t, err) - assert.EqualValues(t, newSetting.SettingValue, settingValue) + assert.Equal(t, newSetting.SettingValue, settingValue) settingValue, err = user_model.GetUserSetting(db.DefaultContext, 99, "no_such") assert.NoError(t, err) - assert.EqualValues(t, "", settingValue) + assert.Empty(t, settingValue) // updated setting updatedSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Updated"} @@ -49,7 +49,7 @@ func TestSettings(t *testing.T) { settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99) assert.NoError(t, err) assert.Len(t, settings, 1) - assert.EqualValues(t, updatedSetting.SettingValue, settings[updatedSetting.SettingKey].SettingValue) + assert.Equal(t, updatedSetting.SettingValue, settings[updatedSetting.SettingKey].SettingValue) // delete setting err = user_model.DeleteUserSetting(db.DefaultContext, 99, keyName) diff --git a/models/user/user.go b/models/user/user.go index 3c72aa7cc4..3b268a6f41 100644 --- a/models/user/user.go +++ b/models/user/user.go @@ -1169,8 +1169,8 @@ func GetUsersByEmails(ctx context.Context, emails []string) (map[string]*User, e needCheckEmails := make(container.Set[string]) needCheckUserNames := make(container.Set[string]) for _, email := range emails { - if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) { - username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) + if strings.HasSuffix(email, "@"+setting.Service.NoReplyAddress) { + username := strings.TrimSuffix(email, "@"+setting.Service.NoReplyAddress) needCheckUserNames.Add(username) } else { needCheckEmails.Add(strings.ToLower(email)) @@ -1232,8 +1232,8 @@ func GetUserByEmail(ctx context.Context, email string) (*User, error) { } // Finally, if email address is the protected email address: - if strings.HasSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) { - username := strings.TrimSuffix(email, fmt.Sprintf("@%s", setting.Service.NoReplyAddress)) + if strings.HasSuffix(email, "@"+setting.Service.NoReplyAddress) { + username := strings.TrimSuffix(email, "@"+setting.Service.NoReplyAddress) user := &User{} has, err := db.GetEngine(ctx).Where("lower_name=?", username).Get(user) if err != nil { diff --git a/models/user/user_test.go b/models/user/user_test.go index 1132c02f28..2d5b6a405c 100644 --- a/models/user/user_test.go +++ b/models/user/user_test.go @@ -83,7 +83,7 @@ func TestSearchUsers(t *testing.T) { cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts) if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) { for i, expectedID := range expectedUserOrOrgIDs { - assert.EqualValues(t, expectedID, users[i].ID, "case: %s", cassText) + assert.Equal(t, expectedID, users[i].ID, "case: %s", cassText) } } } @@ -513,7 +513,7 @@ func Test_ValidateUser(t *testing.T) { {ID: 2, Visibility: structs.VisibleTypePrivate}: true, } for kase, expected := range kases { - assert.EqualValues(t, expected, nil == user_model.ValidateUser(kase), "case: %+v", kase) + assert.Equal(t, expected, nil == user_model.ValidateUser(kase), "case: %+v", kase) } } @@ -537,7 +537,7 @@ func Test_NormalizeUserFromEmail(t *testing.T) { for _, testCase := range testCases { normalizedName, err := user_model.NormalizeUserName(testCase.Input) assert.NoError(t, err) - assert.EqualValues(t, testCase.Expected, normalizedName) + assert.Equal(t, testCase.Expected, normalizedName) if testCase.IsNormalizedValid { assert.NoError(t, user_model.IsUsableUsername(normalizedName)) } else { @@ -564,7 +564,7 @@ func TestEmailTo(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.result, func(t *testing.T) { testUser := &user_model.User{FullName: testCase.fullName, Email: testCase.mail} - assert.EqualValues(t, testCase.result, testUser.EmailTo()) + assert.Equal(t, testCase.result, testUser.EmailTo()) }) } } diff --git a/models/webhook/webhook_test.go b/models/webhook/webhook_test.go index 6ff77a380d..29f7735d09 100644 --- a/models/webhook/webhook_test.go +++ b/models/webhook/webhook_test.go @@ -67,7 +67,7 @@ func TestWebhook_UpdateEvent(t *testing.T) { } func TestWebhook_EventsArray(t *testing.T) { - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "create", "delete", "fork", "push", "issues", "issue_assign", "issue_label", "issue_milestone", "issue_comment", "pull_request", "pull_request_assign", "pull_request_label", "pull_request_milestone", diff --git a/modules/actions/workflows.go b/modules/actions/workflows.go index 0d2b0dd919..a538b6e290 100644 --- a/modules/actions/workflows.go +++ b/modules/actions/workflows.go @@ -463,7 +463,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa matchTimes++ } case "paths": - filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase) if err != nil { log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err) } else { @@ -476,7 +476,7 @@ func matchPullRequestEvent(gitRepo *git.Repository, commit *git.Commit, prPayloa } } case "paths-ignore": - filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.Base.Ref) + filesChanged, err := headCommit.GetFilesChangedSinceCommit(prPayload.PullRequest.MergeBase) if err != nil { log.Error("GetFilesChangedSinceCommit [commit_sha1: %s]: %v", headCommit.ID.String(), err) } else { diff --git a/modules/assetfs/layered_test.go b/modules/assetfs/layered_test.go index 03a3ae0d7c..b549815ea5 100644 --- a/modules/assetfs/layered_test.go +++ b/modules/assetfs/layered_test.go @@ -52,7 +52,7 @@ func TestLayered(t *testing.T) { assert.NoError(t, err) bs, err := io.ReadAll(f) assert.NoError(t, err) - assert.EqualValues(t, "f1", string(bs)) + assert.Equal(t, "f1", string(bs)) _ = f.Close() assertRead := func(expected string, expectedErr error, elems ...string) { @@ -76,27 +76,27 @@ func TestLayered(t *testing.T) { files, err := assets.ListFiles(".", true) assert.NoError(t, err) - assert.EqualValues(t, []string{"f1", "f2", "fa"}, files) + assert.Equal(t, []string{"f1", "f2", "fa"}, files) files, err = assets.ListFiles(".", false) assert.NoError(t, err) - assert.EqualValues(t, []string{"d1", "d2", "da"}, files) + assert.Equal(t, []string{"d1", "d2", "da"}, files) files, err = assets.ListFiles(".") assert.NoError(t, err) - assert.EqualValues(t, []string{"d1", "d2", "da", "f1", "f2", "fa"}, files) + assert.Equal(t, []string{"d1", "d2", "da", "f1", "f2", "fa"}, files) files, err = assets.ListAllFiles(".", true) assert.NoError(t, err) - assert.EqualValues(t, []string{"d1/f", "d2/f", "da/f", "f1", "f2", "fa"}, files) + assert.Equal(t, []string{"d1/f", "d2/f", "da/f", "f1", "f2", "fa"}, files) files, err = assets.ListAllFiles(".", false) assert.NoError(t, err) - assert.EqualValues(t, []string{"d1", "d2", "da", "da/sub1", "da/sub2"}, files) + assert.Equal(t, []string{"d1", "d2", "da", "da/sub1", "da/sub2"}, files) files, err = assets.ListAllFiles(".") assert.NoError(t, err) - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "d1", "d1/f", "d2", "d2/f", "da", "da/f", "da/sub1", "da/sub2", @@ -104,6 +104,6 @@ func TestLayered(t *testing.T) { }, files) assert.Empty(t, assets.GetFileLayerName("no-such")) - assert.EqualValues(t, "l1", assets.GetFileLayerName("f1")) - assert.EqualValues(t, "l2", assets.GetFileLayerName("f2")) + assert.Equal(t, "l1", assets.GetFileLayerName("f1")) + assert.Equal(t, "l2", assets.GetFileLayerName("f2")) } diff --git a/modules/avatar/avatar_test.go b/modules/avatar/avatar_test.go index a721c77868..a5a1a7c1b0 100644 --- a/modules/avatar/avatar_test.go +++ b/modules/avatar/avatar_test.go @@ -94,8 +94,8 @@ func Test_ProcessAvatarImage(t *testing.T) { assert.NotEqual(t, origin, result) decoded, err := png.Decode(bytes.NewReader(result)) assert.NoError(t, err) - assert.EqualValues(t, scaledSize, decoded.Bounds().Max.X) - assert.EqualValues(t, scaledSize, decoded.Bounds().Max.Y) + assert.Equal(t, scaledSize, decoded.Bounds().Max.X) + assert.Equal(t, scaledSize, decoded.Bounds().Max.Y) // if origin image is smaller than the default size, use the origin image origin = newImgData(1) diff --git a/modules/avatar/hash_test.go b/modules/avatar/hash_test.go index 1b8249c696..c518144b47 100644 --- a/modules/avatar/hash_test.go +++ b/modules/avatar/hash_test.go @@ -19,8 +19,8 @@ func Test_HashAvatar(t *testing.T) { var buff bytes.Buffer png.Encode(&buff, myImage) - assert.EqualValues(t, "9ddb5bac41d57e72aa876321d0c09d71090c05f94bc625303801be2f3240d2cb", avatar.HashAvatar(1, buff.Bytes())) - assert.EqualValues(t, "9a5d44e5d637b9582a976676e8f3de1dccd877c2fe3e66ca3fab1629f2f47609", avatar.HashAvatar(8, buff.Bytes())) - assert.EqualValues(t, "ed7399158672088770de6f5211ce15528ebd675e92fc4fc060c025f4b2794ccb", avatar.HashAvatar(1024, buff.Bytes())) - assert.EqualValues(t, "161178642c7d59eb25a61dddced5e6b66eae1c70880d5f148b1b497b767e72d9", avatar.HashAvatar(1024, []byte{})) + assert.Equal(t, "9ddb5bac41d57e72aa876321d0c09d71090c05f94bc625303801be2f3240d2cb", avatar.HashAvatar(1, buff.Bytes())) + assert.Equal(t, "9a5d44e5d637b9582a976676e8f3de1dccd877c2fe3e66ca3fab1629f2f47609", avatar.HashAvatar(8, buff.Bytes())) + assert.Equal(t, "ed7399158672088770de6f5211ce15528ebd675e92fc4fc060c025f4b2794ccb", avatar.HashAvatar(1024, buff.Bytes())) + assert.Equal(t, "161178642c7d59eb25a61dddced5e6b66eae1c70880d5f148b1b497b767e72d9", avatar.HashAvatar(1024, []byte{})) } diff --git a/modules/avatar/identicon/identicon.go b/modules/avatar/identicon/identicon.go index 63926d5f19..87bd87796e 100644 --- a/modules/avatar/identicon/identicon.go +++ b/modules/avatar/identicon/identicon.go @@ -8,6 +8,7 @@ package identicon import ( "crypto/sha256" + "errors" "fmt" "image" "image/color" @@ -29,7 +30,7 @@ type Identicon struct { // fore all possible foreground colors. only one foreground color will be picked randomly for one image func New(size int, back color.Color, fore ...color.Color) (*Identicon, error) { if len(fore) == 0 { - return nil, fmt.Errorf("foreground is not set") + return nil, errors.New("foreground is not set") } if size < minImageSize { diff --git a/modules/badge/badge.go b/modules/badge/badge.go index fdf9866f60..d2e9bd9d1b 100644 --- a/modules/badge/badge.go +++ b/modules/badge/badge.go @@ -5,6 +5,7 @@ package badge import ( "strings" + "sync" "unicode" actions_model "code.gitea.io/gitea/models/actions" @@ -49,23 +50,40 @@ func (b Badge) Width() int { return b.Label.width + b.Message.width } +// Style follows https://shields.io/badges +const ( + StyleFlat = "flat" + StyleFlatSquare = "flat-square" +) + const ( defaultOffset = 10 defaultFontSize = 11 DefaultColor = "#9f9f9f" // Grey DefaultFontFamily = "DejaVu Sans,Verdana,Geneva,sans-serif" + DefaultStyle = StyleFlat ) -var StatusColorMap = map[actions_model.Status]string{ - actions_model.StatusSuccess: "#4c1", // Green - actions_model.StatusSkipped: "#dfb317", // Yellow - actions_model.StatusUnknown: "#97ca00", // Light Green - actions_model.StatusFailure: "#e05d44", // Red - actions_model.StatusCancelled: "#fe7d37", // Orange - actions_model.StatusWaiting: "#dfb317", // Yellow - actions_model.StatusRunning: "#dfb317", // Yellow - actions_model.StatusBlocked: "#dfb317", // Yellow -} +var GlobalVars = sync.OnceValue(func() (ret struct { + StatusColorMap map[actions_model.Status]string + DejaVuGlyphWidthData map[rune]uint8 + AllStyles []string +}, +) { + ret.StatusColorMap = map[actions_model.Status]string{ + actions_model.StatusSuccess: "#4c1", // Green + actions_model.StatusSkipped: "#dfb317", // Yellow + actions_model.StatusUnknown: "#97ca00", // Light Green + actions_model.StatusFailure: "#e05d44", // Red + actions_model.StatusCancelled: "#fe7d37", // Orange + actions_model.StatusWaiting: "#dfb317", // Yellow + actions_model.StatusRunning: "#dfb317", // Yellow + actions_model.StatusBlocked: "#dfb317", // Yellow + } + ret.DejaVuGlyphWidthData = dejaVuGlyphWidthDataFunc() + ret.AllStyles = []string{StyleFlat, StyleFlatSquare} + return ret +}) // GenerateBadge generates badge with given template func GenerateBadge(label, message, color string) Badge { @@ -93,7 +111,7 @@ func GenerateBadge(label, message, color string) Badge { func calculateTextWidth(text string) int { width := 0 - widthData := DejaVuGlyphWidthData() + widthData := GlobalVars().DejaVuGlyphWidthData for _, char := range strings.TrimSpace(text) { charWidth, ok := widthData[char] if !ok { diff --git a/modules/badge/badge_glyph_width.go b/modules/badge/badge_glyph_width.go index e8e43ec9cb..0d950c5a70 100644 --- a/modules/badge/badge_glyph_width.go +++ b/modules/badge/badge_glyph_width.go @@ -3,8 +3,6 @@ package badge -import "sync" - // DejaVuGlyphWidthData is generated by `sfnt.Face.GlyphAdvance(nil, , 11, font.HintingNone)` with DejaVu Sans // v2.37 (https://github.com/dejavu-fonts/dejavu-fonts/releases/download/version_2_37/dejavu-sans-ttf-2.37.zip). // @@ -13,7 +11,7 @@ import "sync" // // A devtest page "/devtest/badge-actions-svg" could be used to check the rendered images. -var DejaVuGlyphWidthData = sync.OnceValue(func() map[rune]uint8 { +func dejaVuGlyphWidthDataFunc() map[rune]uint8 { return map[rune]uint8{ 32: 3, 33: 4, @@ -205,4 +203,4 @@ var DejaVuGlyphWidthData = sync.OnceValue(func() map[rune]uint8 { 254: 7, 255: 7, } -}) +} diff --git a/modules/cache/cache.go b/modules/cache/cache.go index f7828e3cae..a434c13b67 100644 --- a/modules/cache/cache.go +++ b/modules/cache/cache.go @@ -4,6 +4,8 @@ package cache import ( + "encoding/hex" + "errors" "fmt" "strconv" "time" @@ -48,10 +50,10 @@ const ( // returns func Test() (time.Duration, error) { if defaultCache == nil { - return 0, fmt.Errorf("default cache not initialized") + return 0, errors.New("default cache not initialized") } - testData := fmt.Sprintf("%x", make([]byte, 500)) + testData := hex.EncodeToString(make([]byte, 500)) start := time.Now() @@ -63,10 +65,10 @@ func Test() (time.Duration, error) { } testVal, hit := defaultCache.Get(testCacheKey) if !hit { - return 0, fmt.Errorf("expect cache hit but got none") + return 0, errors.New("expect cache hit but got none") } if testVal != testData { - return 0, fmt.Errorf("expect cache to return same value as stored but got other") + return 0, errors.New("expect cache to return same value as stored but got other") } return time.Since(start), nil diff --git a/modules/cache/cache_test.go b/modules/cache/cache_test.go index 5408020306..d6ea2032ee 100644 --- a/modules/cache/cache_test.go +++ b/modules/cache/cache_test.go @@ -4,7 +4,7 @@ package cache import ( - "fmt" + "errors" "testing" "time" @@ -57,22 +57,22 @@ func TestGetString(t *testing.T) { createTestCache() data, err := GetString("key", func() (string, error) { - return "", fmt.Errorf("some error") + return "", errors.New("some error") }) assert.Error(t, err) - assert.Equal(t, "", data) + assert.Empty(t, data) data, err = GetString("key", func() (string, error) { return "", nil }) assert.NoError(t, err) - assert.Equal(t, "", data) + assert.Empty(t, data) data, err = GetString("key", func() (string, error) { return "some data", nil }) assert.NoError(t, err) - assert.Equal(t, "", data) + assert.Empty(t, data) Remove("key") data, err = GetString("key", func() (string, error) { @@ -82,7 +82,7 @@ func TestGetString(t *testing.T) { assert.Equal(t, "some data", data) data, err = GetString("key", func() (string, error) { - return "", fmt.Errorf("some error") + return "", errors.New("some error") }) assert.NoError(t, err) assert.Equal(t, "some data", data) @@ -93,7 +93,7 @@ func TestGetInt64(t *testing.T) { createTestCache() data, err := GetInt64("key", func() (int64, error) { - return 0, fmt.Errorf("some error") + return 0, errors.New("some error") }) assert.Error(t, err) assert.EqualValues(t, 0, data) @@ -118,7 +118,7 @@ func TestGetInt64(t *testing.T) { assert.EqualValues(t, 100, data) data, err = GetInt64("key", func() (int64, error) { - return 0, fmt.Errorf("some error") + return 0, errors.New("some error") }) assert.NoError(t, err) assert.EqualValues(t, 100, data) diff --git a/modules/cache/context_test.go b/modules/cache/context_test.go index cfc186a7bd..decb532937 100644 --- a/modules/cache/context_test.go +++ b/modules/cache/context_test.go @@ -22,7 +22,7 @@ func TestWithCacheContext(t *testing.T) { SetContextData(ctx, field, "my_config1", 1) v = GetContextData(ctx, field, "my_config1") assert.NotNil(t, v) - assert.EqualValues(t, 1, v.(int)) + assert.Equal(t, 1, v.(int)) RemoveContextData(ctx, field, "my_config1") RemoveContextData(ctx, field, "my_config2") // remove a non-exist key @@ -34,7 +34,7 @@ func TestWithCacheContext(t *testing.T) { return 1, nil }) assert.NoError(t, err) - assert.EqualValues(t, 1, vInt) + assert.Equal(t, 1, vInt) v = GetContextData(ctx, field, "my_config1") assert.EqualValues(t, 1, v) diff --git a/modules/charset/ambiguous_gen_test.go b/modules/charset/ambiguous_gen_test.go index 221c27d0e1..d3be0b1a13 100644 --- a/modules/charset/ambiguous_gen_test.go +++ b/modules/charset/ambiguous_gen_test.go @@ -14,7 +14,7 @@ import ( 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.Len(t, ambiguous.With, len(ambiguous.Confusable)) assert.True(t, sort.SliceIsSorted(ambiguous.Confusable, func(i, j int) bool { return ambiguous.Confusable[i] < ambiguous.Confusable[j] })) diff --git a/modules/charset/charset_test.go b/modules/charset/charset_test.go index 19b1303365..1fb362654d 100644 --- a/modules/charset/charset_test.go +++ b/modules/charset/charset_test.go @@ -252,7 +252,7 @@ func TestToUTF8WithFallbackReader(t *testing.T) { input += "// Выключаем" rd := ToUTF8WithFallbackReader(bytes.NewReader([]byte(input)), ConvertOpts{}) r, _ := io.ReadAll(rd) - assert.EqualValuesf(t, input, string(r), "testing string len=%d", testLen) + assert.Equalf(t, input, string(r), "testing string len=%d", testLen) } truncatedOneByteExtension := failFastBytes diff --git a/modules/csv/csv_test.go b/modules/csv/csv_test.go index 25945113a7..be9fc5f823 100644 --- a/modules/csv/csv_test.go +++ b/modules/csv/csv_test.go @@ -99,10 +99,10 @@ j, ,\x20 for n, c := range cases { rd, err := CreateReaderAndDetermineDelimiter(nil, strings.NewReader(decodeSlashes(t, c.csv))) assert.NoError(t, err, "case %d: should not throw error: %v\n", n, err) - assert.EqualValues(t, c.expectedDelimiter, rd.Comma, "case %d: delimiter should be '%c', got '%c'", n, c.expectedDelimiter, rd.Comma) + assert.Equal(t, c.expectedDelimiter, rd.Comma, "case %d: delimiter should be '%c', got '%c'", n, c.expectedDelimiter, rd.Comma) rows, err := rd.ReadAll() assert.NoError(t, err, "case %d: should not throw error: %v\n", n, err) - assert.EqualValues(t, c.expectedRows, rows, "case %d: rows should be equal", n) + assert.Equal(t, c.expectedRows, rows, "case %d: rows should be equal", n) } } @@ -231,7 +231,7 @@ John Doe john@doe.com This,note,had,a,lot,of,commas,to,test,delimiters`, for n, c := range cases { delimiter := determineDelimiter(markup.NewRenderContext(t.Context()).WithRelativePath(c.filename), []byte(decodeSlashes(t, c.csv))) - assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) + assert.Equal(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) } } @@ -296,7 +296,7 @@ abc | |123 for n, c := range cases { modifiedText := removeQuotedString(decodeSlashes(t, c.text)) - assert.EqualValues(t, c.expectedText, modifiedText, "case %d: modified text should be equal", n) + assert.Equal(t, c.expectedText, modifiedText, "case %d: modified text should be equal", n) } } @@ -451,7 +451,7 @@ jkl`, for n, c := range cases { delimiter := guessDelimiter([]byte(decodeSlashes(t, c.csv))) - assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) + assert.Equal(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) } } @@ -543,7 +543,7 @@ a|"he said, ""here I am"""`, for n, c := range cases { delimiter := guessFromBeforeAfterQuotes([]byte(decodeSlashes(t, c.csv))) - assert.EqualValues(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) + assert.Equal(t, c.expectedDelimiter, delimiter, "case %d: delimiter should be equal, expected '%c' got '%c'", n, c.expectedDelimiter, delimiter) } } @@ -579,7 +579,7 @@ func TestFormatError(t *testing.T) { assert.Error(t, err, "case %d: expected an error to be returned", n) } else { assert.NoError(t, err, "case %d: no error was expected, got error: %v", n, err) - assert.EqualValues(t, c.expectedMessage, message, "case %d: messages should be equal, expected '%s' got '%s'", n, c.expectedMessage, message) + assert.Equal(t, c.expectedMessage, message, "case %d: messages should be equal, expected '%s' got '%s'", n, c.expectedMessage, message) } } } diff --git a/modules/dump/dumper_test.go b/modules/dump/dumper_test.go index 2db3a598a4..8f06c1851d 100644 --- a/modules/dump/dumper_test.go +++ b/modules/dump/dumper_test.go @@ -103,11 +103,11 @@ func TestDumper(t *testing.T) { d.GlobalExcludeAbsPath(filepath.Join(tmpDir, "include/exclude1")) err := d.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), []string{filepath.Join(tmpDir, "include/exclude2")}) assert.NoError(t, err) - assert.EqualValues(t, sortStrings([]string{"include/a", "include/sub", "include/sub/b"}), sortStrings(tw.added)) + assert.Equal(t, sortStrings([]string{"include/a", "include/sub", "include/sub/b"}), sortStrings(tw.added)) tw = &testWriter{} d = &Dumper{Writer: tw} err = d.AddRecursiveExclude("include", filepath.Join(tmpDir, "include"), nil) assert.NoError(t, err) - assert.EqualValues(t, sortStrings([]string{"include/exclude2", "include/exclude2/a-2", "include/a", "include/sub", "include/sub/b", "include/exclude1", "include/exclude1/a-1"}), sortStrings(tw.added)) + assert.Equal(t, sortStrings([]string{"include/exclude2", "include/exclude2/a-2", "include/a", "include/sub", "include/sub/b", "include/exclude1", "include/exclude1/a-1"}), sortStrings(tw.added)) } diff --git a/modules/fileicon/material.go b/modules/fileicon/material.go index aa31cd8d7c..557f7ca9e4 100644 --- a/modules/fileicon/material.go +++ b/modules/fileicon/material.go @@ -13,7 +13,6 @@ import ( "code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/options" - "code.gitea.io/gitea/modules/reqctx" "code.gitea.io/gitea/modules/svg" ) @@ -62,13 +61,7 @@ func (m *MaterialIconProvider) loadData() { log.Debug("Loaded material icon rules and SVG images") } -func (m *MaterialIconProvider) renderFileIconSVG(ctx reqctx.RequestContext, name, svg, extraClass string) template.HTML { - data := ctx.GetData() - renderedSVGs, _ := data["_RenderedSVGs"].(map[string]bool) - if renderedSVGs == nil { - renderedSVGs = make(map[string]bool) - data["_RenderedSVGs"] = renderedSVGs - } +func (m *MaterialIconProvider) renderFileIconSVG(p *RenderedIconPool, name, svg, extraClass string) template.HTML { // This part is a bit hacky, but it works really well. It should be safe to do so because all SVG icons are generated by us. // Will try to refactor this in the future. if !strings.HasPrefix(svg, "') - if renderedSVGs[svgID] && posOuterBefore != -1 { - return template.HTML(``) + if p.IconSVGs[svgID] == "" { + p.IconSVGs[svgID] = template.HTML(``) } -func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.TreeEntry) template.HTML { +func (m *MaterialIconProvider) FileIcon(p *RenderedIconPool, entry *git.TreeEntry) template.HTML { if m.rules == nil { return BasicThemeIcon(entry) } @@ -99,12 +89,9 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr } name := m.findIconNameByGit(entry) - if name == "folder" { - // the material icon pack's "folder" icon doesn't look good, so use our built-in one - // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work - return svg.RenderHTML("material-folder-generic", 16, "octicon-file-directory-fill") - } - if iconSVG, ok := m.svgs[name]; ok && iconSVG != "" { + // the material icon pack's "folder" icon doesn't look good, so use our built-in one + // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work + if iconSVG, ok := m.svgs[name]; ok && name != "folder" && iconSVG != "" { // keep the old "octicon-xxx" class name to make some "theme plugin selector" could still work extraClass := "octicon-file" switch { @@ -113,9 +100,10 @@ func (m *MaterialIconProvider) FileIcon(ctx reqctx.RequestContext, entry *git.Tr case entry.IsSubModule(): extraClass = "octicon-file-submodule" } - return m.renderFileIconSVG(ctx, name, iconSVG, extraClass) + return m.renderFileIconSVG(p, name, iconSVG, extraClass) } - return svg.RenderHTML("octicon-file") + // TODO: use an interface or wrapper for git.Entry to make the code testable. + return BasicThemeIcon(entry) } func (m *MaterialIconProvider) findIconNameWithLangID(s string) string { diff --git a/modules/fileicon/render.go b/modules/fileicon/render.go new file mode 100644 index 0000000000..1d014693fd --- /dev/null +++ b/modules/fileicon/render.go @@ -0,0 +1,52 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package fileicon + +import ( + "html/template" + "strings" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" +) + +type RenderedIconPool struct { + IconSVGs map[string]template.HTML +} + +func NewRenderedIconPool() *RenderedIconPool { + return &RenderedIconPool{ + IconSVGs: make(map[string]template.HTML), + } +} + +func (p *RenderedIconPool) RenderToHTML() template.HTML { + if len(p.IconSVGs) == 0 { + return "" + } + sb := &strings.Builder{} + sb.WriteString(``) + for _, icon := range p.IconSVGs { + sb.WriteString(string(icon)) + } + sb.WriteString(``) + return template.HTML(sb.String()) +} + +// TODO: use an interface or struct to replace "*git.TreeEntry", to decouple the fileicon module from git module + +func RenderEntryIcon(renderedIconPool *RenderedIconPool, entry *git.TreeEntry) template.HTML { + if setting.UI.FileIconTheme == "material" { + return DefaultMaterialIconProvider().FileIcon(renderedIconPool, entry) + } + return BasicThemeIcon(entry) +} + +func RenderEntryIconOpen(renderedIconPool *RenderedIconPool, entry *git.TreeEntry) template.HTML { + // TODO: add "open icon" support + if setting.UI.FileIconTheme == "material" { + return DefaultMaterialIconProvider().FileIcon(renderedIconPool, entry) + } + return BasicThemeIcon(entry) +} diff --git a/modules/git/command_test.go b/modules/git/command_test.go index 005a760ed1..eb112707e7 100644 --- a/modules/git/command_test.go +++ b/modules/git/command_test.go @@ -54,8 +54,8 @@ func TestGitArgument(t *testing.T) { func TestCommandString(t *testing.T) { cmd := NewCommandNoGlobals("a", "-m msg", "it's a test", `say "hello"`) - assert.EqualValues(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString()) + assert.Equal(t, cmd.prog+` a "-m msg" "it's a test" "say \"hello\""`, cmd.LogString()) cmd = NewCommandNoGlobals("url: https://a:b@c/", "/root/dir-a/dir-b") - assert.EqualValues(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString()) + assert.Equal(t, cmd.prog+` "url: https://sanitized-credential@c/" .../dir-a/dir-b`, cmd.LogString()) } diff --git a/modules/git/commit_sha256_test.go b/modules/git/commit_sha256_test.go index f6ca83c9ed..64a0f53908 100644 --- a/modules/git/commit_sha256_test.go +++ b/modules/git/commit_sha256_test.go @@ -97,7 +97,7 @@ signed commit` assert.NoError(t, err) require.NotNil(t, commitFromReader) assert.EqualValues(t, sha, commitFromReader.ID) - assert.EqualValues(t, `-----BEGIN PGP SIGNATURE----- + assert.Equal(t, `-----BEGIN PGP SIGNATURE----- iQIrBAABCgAtFiEES+fB08xlgTrzSdQvhkUIsBsmec8FAmU/wKoPHGFtYWplckBz dXNlLmRlAAoJEIZFCLAbJnnP4s4PQIJATa++WPzR6/H4etT7bsOGoMyguEJYyWOd @@ -114,19 +114,19 @@ HKRr3NlRM/DygzTyj0gN74uoa0goCIbyAQhiT42nm0cuhM7uN/W0ayrlZjGF1cbR =xybZ -----END PGP SIGNATURE----- `, commitFromReader.Signature.Signature) - assert.EqualValues(t, `tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e + assert.Equal(t, `tree e7f9e96dd79c09b078cac8b303a7d3b9d65ff9b734e86060a4d20409fd379f9e parent 26e9ccc29fad747e9c5d9f4c9ddeb7eff61cc45ef6a8dc258cbeb181afc055e8 author Adam Majer 1698676906 +0100 committer Adam Majer 1698676906 +0100 signed commit`, commitFromReader.Signature.Payload) - assert.EqualValues(t, "Adam Majer ", commitFromReader.Author.String()) + assert.Equal(t, "Adam Majer ", commitFromReader.Author.String()) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) commitFromReader.CommitMessage += "\n\n" commitFromReader.Signature.Payload += "\n\n" - assert.EqualValues(t, commitFromReader, commitFromReader2) + assert.Equal(t, commitFromReader, commitFromReader2) } func TestHasPreviousCommitSha256(t *testing.T) { diff --git a/modules/git/commit_test.go b/modules/git/commit_test.go index 5319e09bb7..f43e0081fd 100644 --- a/modules/git/commit_test.go +++ b/modules/git/commit_test.go @@ -93,7 +93,7 @@ empty commit` assert.NoError(t, err) require.NotNil(t, commitFromReader) assert.EqualValues(t, sha, commitFromReader.ID) - assert.EqualValues(t, `-----BEGIN PGP SIGNATURE----- + assert.Equal(t, `-----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEWPb2jX6FS2mqyJRQLmK0HJOGlEMFAl00zmEACgkQLmK0HJOG lEMDFBAAhQKKqLD1VICygJMEB8t1gBmNLgvziOLfpX4KPWdPtBk3v/QJ7OrfMrVK @@ -110,19 +110,19 @@ mfeFhT57UbE4qukTDIQ0Y0WM40UYRTakRaDY7ubhXgLgx09Cnp9XTVMsHgT6j9/i =FRsO -----END PGP SIGNATURE----- `, commitFromReader.Signature.Signature) - assert.EqualValues(t, `tree f1a6cb52b2d16773290cefe49ad0684b50a4f930 + assert.Equal(t, `tree f1a6cb52b2d16773290cefe49ad0684b50a4f930 parent 37991dec2c8e592043f47155ce4808d4580f9123 author silverwind 1563741793 +0200 committer silverwind 1563741793 +0200 empty commit`, commitFromReader.Signature.Payload) - assert.EqualValues(t, "silverwind ", commitFromReader.Author.String()) + assert.Equal(t, "silverwind ", commitFromReader.Author.String()) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) commitFromReader.CommitMessage += "\n\n" commitFromReader.Signature.Payload += "\n\n" - assert.EqualValues(t, commitFromReader, commitFromReader2) + assert.Equal(t, commitFromReader, commitFromReader2) } func TestCommitWithEncodingFromReader(t *testing.T) { @@ -159,7 +159,7 @@ ISO-8859-1` assert.NoError(t, err) require.NotNil(t, commitFromReader) assert.EqualValues(t, sha, commitFromReader.ID) - assert.EqualValues(t, `-----BEGIN PGP SIGNATURE----- + assert.Equal(t, `-----BEGIN PGP SIGNATURE----- iQGzBAABCgAdFiEE9HRrbqvYxPT8PXbefPSEkrowAa8FAmYGg7IACgkQfPSEkrow Aa9olwv+P0HhtCM6CRvlUmPaqswRsDPNR4i66xyXGiSxdI9V5oJL7HLiQIM7KrFR @@ -174,20 +174,20 @@ jw4YcO5u =r3UU -----END PGP SIGNATURE----- `, commitFromReader.Signature.Signature) - assert.EqualValues(t, `tree ca3fad42080dd1a6d291b75acdfc46e5b9b307e5 + assert.Equal(t, `tree ca3fad42080dd1a6d291b75acdfc46e5b9b307e5 parent 47b24e7ab977ed31c5a39989d570847d6d0052af author KN4CK3R 1711702962 +0100 committer KN4CK3R 1711702962 +0100 encoding ISO-8859-1 ISO-8859-1`, commitFromReader.Signature.Payload) - assert.EqualValues(t, "KN4CK3R ", commitFromReader.Author.String()) + assert.Equal(t, "KN4CK3R ", commitFromReader.Author.String()) commitFromReader2, err := CommitFromReader(gitRepo, sha, strings.NewReader(commitString+"\n\n")) assert.NoError(t, err) commitFromReader.CommitMessage += "\n\n" commitFromReader.Signature.Payload += "\n\n" - assert.EqualValues(t, commitFromReader, commitFromReader2) + assert.Equal(t, commitFromReader, commitFromReader2) } func TestHasPreviousCommit(t *testing.T) { @@ -351,10 +351,10 @@ func Test_GetCommitBranchStart(t *testing.T) { defer repo.Close() commit, err := repo.GetBranchCommit("branch1") assert.NoError(t, err) - assert.EqualValues(t, "2839944139e0de9737a044f78b0e4b40d989a9e3", commit.ID.String()) + assert.Equal(t, "2839944139e0de9737a044f78b0e4b40d989a9e3", commit.ID.String()) startCommitID, err := repo.GetCommitBranchStart(os.Environ(), "branch1", commit.ID.String()) assert.NoError(t, err) assert.NotEmpty(t, startCommitID) - assert.EqualValues(t, "95bb4d39648ee7e325106df01a621c530863a653", startCommitID) + assert.Equal(t, "95bb4d39648ee7e325106df01a621c530863a653", startCommitID) } diff --git a/modules/git/diff_test.go b/modules/git/diff_test.go index 0f865c52a8..9a09347b30 100644 --- a/modules/git/diff_test.go +++ b/modules/git/diff_test.go @@ -177,8 +177,8 @@ func ExampleCutDiffAroundLine() { func TestParseDiffHunkString(t *testing.T) { leftLine, leftHunk, rightLine, rightHunk := ParseDiffHunkString("@@ -19,3 +19,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER") - assert.EqualValues(t, 19, leftLine) - assert.EqualValues(t, 3, leftHunk) - assert.EqualValues(t, 19, rightLine) - assert.EqualValues(t, 5, rightHunk) + assert.Equal(t, 19, leftLine) + assert.Equal(t, 3, leftHunk) + assert.Equal(t, 19, rightLine) + assert.Equal(t, 5, rightHunk) } diff --git a/modules/git/error.go b/modules/git/error.go index 10fb37be07..6c86d1b04d 100644 --- a/modules/git/error.go +++ b/modules/git/error.go @@ -32,19 +32,19 @@ func (err ErrNotExist) Unwrap() error { return util.ErrNotExist } -// ErrBadLink entry.FollowLink error -type ErrBadLink struct { +// ErrSymlinkUnresolved entry.FollowLink error +type ErrSymlinkUnresolved struct { Name string Message string } -func (err ErrBadLink) Error() string { +func (err ErrSymlinkUnresolved) Error() string { return fmt.Sprintf("%s: %s", err.Name, err.Message) } -// IsErrBadLink if some error is ErrBadLink -func IsErrBadLink(err error) bool { - _, ok := err.(ErrBadLink) +// IsErrSymlinkUnresolved if some error is ErrSymlinkUnresolved +func IsErrSymlinkUnresolved(err error) bool { + _, ok := err.(ErrSymlinkUnresolved) return ok } diff --git a/modules/git/grep.go b/modules/git/grep.go index 51ebcb832f..66711650c9 100644 --- a/modules/git/grep.go +++ b/modules/git/grep.go @@ -61,7 +61,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO */ var results []*GrepResult cmd := NewCommand("grep", "--null", "--break", "--heading", "--line-number", "--full-name") - cmd.AddOptionValues("--context", fmt.Sprint(opts.ContextLineNumber)) + cmd.AddOptionValues("--context", strconv.Itoa(opts.ContextLineNumber)) switch opts.GrepMode { case GrepModeExact: cmd.AddArguments("--fixed-strings") diff --git a/modules/git/object_id.go b/modules/git/object_id.go index 82d30184df..25dfef3ec5 100644 --- a/modules/git/object_id.go +++ b/modules/git/object_id.go @@ -99,5 +99,5 @@ type ErrInvalidSHA struct { } func (err ErrInvalidSHA) Error() string { - return fmt.Sprintf("invalid sha: %s", err.SHA) + return "invalid sha: " + err.SHA } diff --git a/modules/git/parse_nogogit_test.go b/modules/git/parse_nogogit_test.go index a4436ce499..6594c84269 100644 --- a/modules/git/parse_nogogit_test.go +++ b/modules/git/parse_nogogit_test.go @@ -58,7 +58,7 @@ func TestParseTreeEntriesLong(t *testing.T) { assert.NoError(t, err) assert.Len(t, entries, len(testCase.Expected)) for i, entry := range entries { - assert.EqualValues(t, testCase.Expected[i], entry) + assert.Equal(t, testCase.Expected[i], entry) } } } @@ -91,7 +91,7 @@ func TestParseTreeEntriesShort(t *testing.T) { assert.NoError(t, err) assert.Len(t, entries, len(testCase.Expected)) for i, entry := range entries { - assert.EqualValues(t, testCase.Expected[i], entry) + assert.Equal(t, testCase.Expected[i], entry) } } } diff --git a/modules/git/repo_attribute.go b/modules/git/repo_attribute.go index 8a5e5fa983..fde42d4730 100644 --- a/modules/git/repo_attribute.go +++ b/modules/git/repo_attribute.go @@ -6,6 +6,7 @@ package git import ( "bytes" "context" + "errors" "fmt" "io" "os" @@ -74,7 +75,7 @@ func (repo *Repository) CheckAttribute(opts CheckAttributeOpts) (map[string]map[ fields := bytes.Split(stdOut.Bytes(), []byte{'\000'}) if len(fields)%3 != 1 { - return nil, fmt.Errorf("wrong number of fields in return from check-attr") + return nil, errors.New("wrong number of fields in return from check-attr") } name2attribute2info := make(map[string]map[string]string) @@ -120,7 +121,7 @@ func (c *CheckAttributeReader) Init(ctx context.Context) error { c.stdOut = lw c.stdOut.Close() - return fmt.Errorf("no provided Attributes to check") + return errors.New("no provided Attributes to check") } c.ctx, c.cancel = context.WithCancel(ctx) diff --git a/modules/git/repo_attribute_test.go b/modules/git/repo_attribute_test.go index e0bde146f6..d8fd9f0e8d 100644 --- a/modules/git/repo_attribute_test.go +++ b/modules/git/repo_attribute_test.go @@ -4,16 +4,10 @@ package git import ( - "context" - mathRand "math/rand/v2" - "path/filepath" - "slices" - "sync" "testing" "time" "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" ) func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { @@ -81,77 +75,23 @@ func Test_nulSeparatedAttributeWriter_ReadAttribute(t *testing.T) { assert.NoError(t, err) attr = <-wr.ReadAttribute() assert.NoError(t, err) - assert.EqualValues(t, attributeTriple{ + assert.Equal(t, attributeTriple{ Filename: "shouldbe.vendor", Attribute: AttributeLinguistVendored, Value: "set", }, attr) attr = <-wr.ReadAttribute() assert.NoError(t, err) - assert.EqualValues(t, attributeTriple{ + assert.Equal(t, attributeTriple{ Filename: "shouldbe.vendor", Attribute: AttributeLinguistGenerated, Value: "unspecified", }, attr) attr = <-wr.ReadAttribute() assert.NoError(t, err) - assert.EqualValues(t, attributeTriple{ + assert.Equal(t, attributeTriple{ Filename: "shouldbe.vendor", Attribute: AttributeLinguistLanguage, Value: "unspecified", }, attr) } - -func TestAttributeReader(t *testing.T) { - t.Skip() // for debug purpose only, do not run in CI - - ctx := t.Context() - - timeout := 1 * time.Second - repoPath := filepath.Join(testReposDir, "language_stats_repo") - commitRef := "HEAD" - - oneRound := func(t *testing.T, roundIdx int) { - ctx, cancel := context.WithTimeout(ctx, timeout) - _ = cancel - gitRepo, err := OpenRepository(ctx, repoPath) - require.NoError(t, err) - defer gitRepo.Close() - - commit, err := gitRepo.GetCommit(commitRef) - require.NoError(t, err) - - files, err := gitRepo.LsFiles() - require.NoError(t, err) - - randomFiles := slices.Clone(files) - randomFiles = append(randomFiles, "any-file-1", "any-file-2") - - t.Logf("Round %v with %d files", roundIdx, len(randomFiles)) - - attrReader, deferrable := gitRepo.CheckAttributeReader(commit.ID.String()) - defer deferrable() - - wg := sync.WaitGroup{} - wg.Add(1) - - go func() { - for { - file := randomFiles[mathRand.IntN(len(randomFiles))] - _, err := attrReader.CheckPath(file) - if err != nil { - for i := 0; i < 10; i++ { - _, _ = attrReader.CheckPath(file) - } - break - } - } - wg.Done() - }() - wg.Wait() - } - - for i := 0; i < 100; i++ { - oneRound(t, i) - } -} diff --git a/modules/git/repo_branch.go b/modules/git/repo_branch.go index 916391f167..e7ecf53f51 100644 --- a/modules/git/repo_branch.go +++ b/modules/git/repo_branch.go @@ -7,7 +7,6 @@ package git import ( "context" "errors" - "fmt" "strings" ) @@ -25,36 +24,6 @@ func IsBranchExist(ctx context.Context, repoPath, name string) bool { return IsReferenceExist(ctx, repoPath, BranchPrefix+name) } -// Branch represents a Git branch. -type Branch struct { - Name string - Path string - - gitRepo *Repository -} - -// GetHEADBranch returns corresponding branch of HEAD. -func (repo *Repository) GetHEADBranch() (*Branch, error) { - if repo == nil { - return nil, fmt.Errorf("nil repo") - } - stdout, _, err := NewCommand("symbolic-ref", "HEAD").RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) - if err != nil { - return nil, err - } - stdout = strings.TrimSpace(stdout) - - if !strings.HasPrefix(stdout, BranchPrefix) { - return nil, fmt.Errorf("invalid HEAD branch: %v", stdout) - } - - return &Branch{ - Name: stdout[len(BranchPrefix):], - Path: stdout, - gitRepo: repo, - }, nil -} - func GetDefaultBranch(ctx context.Context, repoPath string) (string, error) { stdout, _, err := NewCommand("symbolic-ref", "HEAD").RunStdString(ctx, &RunOpts{Dir: repoPath}) if err != nil { @@ -67,37 +36,6 @@ func GetDefaultBranch(ctx context.Context, repoPath string) (string, error) { return strings.TrimPrefix(stdout, BranchPrefix), nil } -// GetBranch returns a branch by it's name -func (repo *Repository) GetBranch(branch string) (*Branch, error) { - if !repo.IsBranchExist(branch) { - return nil, ErrBranchNotExist{branch} - } - return &Branch{ - Path: repo.Path, - Name: branch, - gitRepo: repo, - }, nil -} - -// GetBranches returns a slice of *git.Branch -func (repo *Repository) GetBranches(skip, limit int) ([]*Branch, int, error) { - brs, countAll, err := repo.GetBranchNames(skip, limit) - if err != nil { - return nil, 0, err - } - - branches := make([]*Branch, len(brs)) - for i := range brs { - branches[i] = &Branch{ - Path: repo.Path, - Name: brs[i], - gitRepo: repo, - } - } - - return branches, countAll, nil -} - // DeleteBranchOptions Option(s) for delete branch type DeleteBranchOptions struct { Force bool @@ -147,11 +85,6 @@ func (repo *Repository) RemoveRemote(name string) error { return err } -// GetCommit returns the head commit of a branch -func (branch *Branch) GetCommit() (*Commit, error) { - return branch.gitRepo.GetBranchCommit(branch.Name) -} - // RenameBranch rename a branch func (repo *Repository) RenameBranch(from, to string) error { _, _, err := NewCommand("branch", "-m").AddDynamicArguments(from, to).RunStdString(repo.Ctx, &RunOpts{Dir: repo.Path}) diff --git a/modules/git/repo_branch_test.go b/modules/git/repo_branch_test.go index cda170d976..8e8ea16fcd 100644 --- a/modules/git/repo_branch_test.go +++ b/modules/git/repo_branch_test.go @@ -21,21 +21,21 @@ func TestRepository_GetBranches(t *testing.T) { assert.NoError(t, err) assert.Len(t, branches, 2) - assert.EqualValues(t, 3, countAll) + assert.Equal(t, 3, countAll) assert.ElementsMatch(t, []string{"master", "branch2"}, branches) branches, countAll, err = bareRepo1.GetBranchNames(0, 0) assert.NoError(t, err) assert.Len(t, branches, 3) - assert.EqualValues(t, 3, countAll) + assert.Equal(t, 3, countAll) assert.ElementsMatch(t, []string{"master", "branch2", "branch1"}, branches) branches, countAll, err = bareRepo1.GetBranchNames(5, 1) assert.NoError(t, err) assert.Empty(t, branches) - assert.EqualValues(t, 3, countAll) + assert.Equal(t, 3, countAll) assert.ElementsMatch(t, []string{}, branches) } @@ -71,15 +71,15 @@ func TestGetRefsBySha(t *testing.T) { // refs/pull/1/head branches, err = bareRepo5.GetRefsBySha("c83380d7056593c51a699d12b9c00627bd5743e9", PullPrefix) assert.NoError(t, err) - assert.EqualValues(t, []string{"refs/pull/1/head"}, branches) + assert.Equal(t, []string{"refs/pull/1/head"}, branches) branches, err = bareRepo5.GetRefsBySha("d8e0bbb45f200e67d9a784ce55bd90821af45ebd", BranchPrefix) assert.NoError(t, err) - assert.EqualValues(t, []string{"refs/heads/master", "refs/heads/master-clone"}, branches) + assert.Equal(t, []string{"refs/heads/master", "refs/heads/master-clone"}, branches) branches, err = bareRepo5.GetRefsBySha("58a4bcc53ac13e7ff76127e0fb518b5262bf09af", BranchPrefix) assert.NoError(t, err) - assert.EqualValues(t, []string{"refs/heads/test-patch-1"}, branches) + assert.Equal(t, []string{"refs/heads/test-patch-1"}, branches) } func BenchmarkGetRefsBySha(b *testing.B) { diff --git a/modules/git/repo_commit_nogogit.go b/modules/git/repo_commit_nogogit.go index 5aa0e9ec04..3ead3e2216 100644 --- a/modules/git/repo_commit_nogogit.go +++ b/modules/git/repo_commit_nogogit.go @@ -81,10 +81,10 @@ func (repo *Repository) getCommit(id ObjectID) (*Commit, error) { _, _ = wr.Write([]byte(id.String() + "\n")) - return repo.getCommitFromBatchReader(rd, id) + return repo.getCommitFromBatchReader(wr, rd, id) } -func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) (*Commit, error) { +func (repo *Repository) getCommitFromBatchReader(wr WriteCloserError, rd *bufio.Reader, id ObjectID) (*Commit, error) { _, typ, size, err := ReadBatchLine(rd) if err != nil { if errors.Is(err, io.EOF) || IsErrNotExist(err) { @@ -112,7 +112,11 @@ func (repo *Repository) getCommitFromBatchReader(rd *bufio.Reader, id ObjectID) return nil, err } - commit, err := tag.Commit(repo) + if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil { + return nil, err + } + + commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object) if err != nil { return nil, err } diff --git a/modules/git/repo_language_stats_test.go b/modules/git/repo_language_stats_test.go index 1ee5f4c3af..81f130bacb 100644 --- a/modules/git/repo_language_stats_test.go +++ b/modules/git/repo_language_stats_test.go @@ -23,14 +23,14 @@ func TestRepository_GetLanguageStats(t *testing.T) { stats, err := gitRepo.GetLanguageStats("8fee858da5796dfb37704761701bb8e800ad9ef3") require.NoError(t, err) - assert.EqualValues(t, map[string]int64{ + assert.Equal(t, map[string]int64{ "Python": 134, "Java": 112, }, stats) } func TestMergeLanguageStats(t *testing.T) { - assert.EqualValues(t, map[string]int64{ + assert.Equal(t, map[string]int64{ "PHP": 1, "python": 10, "JAVA": 700, diff --git a/modules/git/repo_stats_test.go b/modules/git/repo_stats_test.go index 3d032385ee..85d8807a6e 100644 --- a/modules/git/repo_stats_test.go +++ b/modules/git/repo_stats_test.go @@ -30,7 +30,7 @@ func TestRepository_GetCodeActivityStats(t *testing.T) { assert.EqualValues(t, 10, code.Additions) assert.EqualValues(t, 1, code.Deletions) assert.Len(t, code.Authors, 3) - assert.EqualValues(t, "tris.git@shoddynet.org", code.Authors[1].Email) + assert.Equal(t, "tris.git@shoddynet.org", code.Authors[1].Email) assert.EqualValues(t, 3, code.Authors[1].Commits) assert.EqualValues(t, 5, code.Authors[0].Commits) } diff --git a/modules/git/repo_tag_nogogit.go b/modules/git/repo_tag_nogogit.go index e0a3104249..3d2b4f52bd 100644 --- a/modules/git/repo_tag_nogogit.go +++ b/modules/git/repo_tag_nogogit.go @@ -41,8 +41,11 @@ func (repo *Repository) GetTagType(id ObjectID) (string, error) { return "", err } _, typ, _, err := ReadBatchLine(rd) - if IsErrNotExist(err) { - return "", ErrNotExist{ID: id.String()} + if err != nil { + if IsErrNotExist(err) { + return "", ErrNotExist{ID: id.String()} + } + return "", err } return typ, nil } diff --git a/modules/git/repo_tag_test.go b/modules/git/repo_tag_test.go index f1f081680a..f1f5ff6664 100644 --- a/modules/git/repo_tag_test.go +++ b/modules/git/repo_tag_test.go @@ -27,12 +27,12 @@ func TestRepository_GetTags(t *testing.T) { } assert.Len(t, tags, 2) assert.Len(t, tags, total) - assert.EqualValues(t, "signed-tag", tags[0].Name) - assert.EqualValues(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String()) - assert.EqualValues(t, "tag", tags[0].Type) - assert.EqualValues(t, "test", tags[1].Name) - assert.EqualValues(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[1].ID.String()) - assert.EqualValues(t, "tag", tags[1].Type) + assert.Equal(t, "signed-tag", tags[0].Name) + assert.Equal(t, "36f97d9a96457e2bab511db30fe2db03893ebc64", tags[0].ID.String()) + assert.Equal(t, "tag", tags[0].Type) + assert.Equal(t, "test", tags[1].Name) + assert.Equal(t, "3ad28a9149a2864384548f3d17ed7f38014c9e8a", tags[1].ID.String()) + assert.Equal(t, "tag", tags[1].Type) } func TestRepository_GetTag(t *testing.T) { @@ -64,18 +64,13 @@ func TestRepository_GetTag(t *testing.T) { // and try to get the Tag for lightweight tag lTag, err := bareRepo1.GetTag(lTagName) - if err != nil { - assert.NoError(t, err) - return - } - if lTag == nil { - assert.NotNil(t, lTag) - assert.FailNow(t, "nil lTag: %s", lTagName) - } - assert.EqualValues(t, lTagName, lTag.Name) - assert.EqualValues(t, lTagCommitID, lTag.ID.String()) - assert.EqualValues(t, lTagCommitID, lTag.Object.String()) - assert.EqualValues(t, "commit", lTag.Type) + require.NoError(t, err) + require.NotNil(t, lTag, "nil lTag: %s", lTagName) + + assert.Equal(t, lTagName, lTag.Name) + assert.Equal(t, lTagCommitID, lTag.ID.String()) + assert.Equal(t, lTagCommitID, lTag.Object.String()) + assert.Equal(t, "commit", lTag.Type) // ANNOTATED TAGS aTagCommitID := "8006ff9adbf0cb94da7dad9e537e53817f9fa5c0" @@ -97,19 +92,14 @@ func TestRepository_GetTag(t *testing.T) { } aTag, err := bareRepo1.GetTag(aTagName) - if err != nil { - assert.NoError(t, err) - return - } - if aTag == nil { - assert.NotNil(t, aTag) - assert.FailNow(t, "nil aTag: %s", aTagName) - } - assert.EqualValues(t, aTagName, aTag.Name) - assert.EqualValues(t, aTagID, aTag.ID.String()) + require.NoError(t, err) + require.NotNil(t, aTag, "nil aTag: %s", aTagName) + + assert.Equal(t, aTagName, aTag.Name) + assert.Equal(t, aTagID, aTag.ID.String()) assert.NotEqual(t, aTagID, aTag.Object.String()) - assert.EqualValues(t, aTagCommitID, aTag.Object.String()) - assert.EqualValues(t, "tag", aTag.Type) + assert.Equal(t, aTagCommitID, aTag.Object.String()) + assert.Equal(t, "tag", aTag.Type) // RELEASE TAGS @@ -127,14 +117,14 @@ func TestRepository_GetTag(t *testing.T) { assert.NoError(t, err) return } - assert.EqualValues(t, rTagCommitID, rTagID) + assert.Equal(t, rTagCommitID, rTagID) oTagID, err := bareRepo1.GetTagID(lTagName) if err != nil { assert.NoError(t, err) return } - assert.EqualValues(t, lTagCommitID, oTagID) + assert.Equal(t, lTagCommitID, oTagID) } func TestRepository_GetAnnotatedTag(t *testing.T) { @@ -170,9 +160,9 @@ func TestRepository_GetAnnotatedTag(t *testing.T) { return } assert.NotNil(t, tag) - assert.EqualValues(t, aTagName, tag.Name) - assert.EqualValues(t, aTagID, tag.ID.String()) - assert.EqualValues(t, "tag", tag.Type) + assert.Equal(t, aTagName, tag.Name) + assert.Equal(t, aTagID, tag.ID.String()) + assert.Equal(t, "tag", tag.Type) // Annotated tag's Commit ID should fail tag2, err := bareRepo1.GetAnnotatedTag(aTagCommitID) diff --git a/modules/git/repo_tree_nogogit.go b/modules/git/repo_tree_nogogit.go index d74769ccb2..1954f85162 100644 --- a/modules/git/repo_tree_nogogit.go +++ b/modules/git/repo_tree_nogogit.go @@ -35,7 +35,11 @@ func (repo *Repository) getTree(id ObjectID) (*Tree, error) { if err != nil { return nil, err } - commit, err := tag.Commit(repo) + + if _, err := wr.Write([]byte(tag.Object.String() + "\n")); err != nil { + return nil, err + } + commit, err := repo.getCommitFromBatchReader(wr, rd, tag.Object) if err != nil { return nil, err } diff --git a/modules/git/signature_test.go b/modules/git/signature_test.go index 92681feea9..b9b5aff61b 100644 --- a/modules/git/signature_test.go +++ b/modules/git/signature_test.go @@ -42,6 +42,6 @@ func TestParseSignatureFromCommitLine(t *testing.T) { } for _, test := range tests { got := parseSignatureFromCommitLine(test.line) - assert.EqualValues(t, test.want, got) + assert.Equal(t, test.want, got) } } diff --git a/modules/git/submodule_test.go b/modules/git/submodule_test.go index fbf8c32e1e..7893b95e3a 100644 --- a/modules/git/submodule_test.go +++ b/modules/git/submodule_test.go @@ -19,11 +19,11 @@ func TestGetTemplateSubmoduleCommits(t *testing.T) { assert.Len(t, submodules, 2) - assert.EqualValues(t, "<°)))><", submodules[0].Path) - assert.EqualValues(t, "d2932de67963f23d43e1c7ecf20173e92ee6c43c", submodules[0].Commit) + assert.Equal(t, "<°)))><", submodules[0].Path) + assert.Equal(t, "d2932de67963f23d43e1c7ecf20173e92ee6c43c", submodules[0].Commit) - assert.EqualValues(t, "libtest", submodules[1].Path) - assert.EqualValues(t, "1234567890123456789012345678901234567890", submodules[1].Commit) + assert.Equal(t, "libtest", submodules[1].Path) + assert.Equal(t, "1234567890123456789012345678901234567890", submodules[1].Commit) } func TestAddTemplateSubmoduleIndexes(t *testing.T) { @@ -42,6 +42,6 @@ func TestAddTemplateSubmoduleIndexes(t *testing.T) { submodules, err := GetTemplateSubmoduleCommits(DefaultContext, tmpDir) require.NoError(t, err) assert.Len(t, submodules, 1) - assert.EqualValues(t, "new-dir", submodules[0].Path) - assert.EqualValues(t, "1234567890123456789012345678901234567890", submodules[0].Commit) + assert.Equal(t, "new-dir", submodules[0].Path) + assert.Equal(t, "1234567890123456789012345678901234567890", submodules[0].Commit) } diff --git a/modules/git/tag.go b/modules/git/tag.go index f7666aa89b..8bf3658d62 100644 --- a/modules/git/tag.go +++ b/modules/git/tag.go @@ -21,11 +21,6 @@ type Tag struct { Signature *CommitSignature } -// Commit return the commit of the tag reference -func (tag *Tag) Commit(gitRepo *Repository) (*Commit, error) { - return gitRepo.getCommit(tag.Object) -} - func parsePayloadSignature(data []byte, messageStart int) (payload, msg, sign string) { pos := messageStart signStart, signEnd := -1, -1 diff --git a/modules/git/tree_entry.go b/modules/git/tree_entry.go index 9513121487..a2e1579290 100644 --- a/modules/git/tree_entry.go +++ b/modules/git/tree_entry.go @@ -8,6 +8,8 @@ import ( "io" "sort" "strings" + + "code.gitea.io/gitea/modules/util" ) // Type returns the type of the entry (commit, tree, blob) @@ -25,7 +27,7 @@ func (te *TreeEntry) Type() string { // FollowLink returns the entry pointed to by a symlink func (te *TreeEntry) FollowLink() (*TreeEntry, error) { if !te.IsLink() { - return nil, ErrBadLink{te.Name(), "not a symlink"} + return nil, ErrSymlinkUnresolved{te.Name(), "not a symlink"} } // read the link @@ -56,13 +58,13 @@ func (te *TreeEntry) FollowLink() (*TreeEntry, error) { } if t == nil { - return nil, ErrBadLink{te.Name(), "points outside of repo"} + return nil, ErrSymlinkUnresolved{te.Name(), "points outside of repo"} } target, err := t.GetTreeEntryByPath(lnk) if err != nil { if IsErrNotExist(err) { - return nil, ErrBadLink{te.Name(), "broken link"} + return nil, ErrSymlinkUnresolved{te.Name(), "broken link"} } return nil, err } @@ -70,33 +72,27 @@ func (te *TreeEntry) FollowLink() (*TreeEntry, error) { } // FollowLinks returns the entry ultimately pointed to by a symlink -func (te *TreeEntry) FollowLinks() (*TreeEntry, error) { +func (te *TreeEntry) FollowLinks(optLimit ...int) (*TreeEntry, error) { if !te.IsLink() { - return nil, ErrBadLink{te.Name(), "not a symlink"} + return nil, ErrSymlinkUnresolved{te.Name(), "not a symlink"} } + limit := util.OptionalArg(optLimit, 10) entry := te - for i := 0; i < 999; i++ { - if entry.IsLink() { - next, err := entry.FollowLink() - if err != nil { - return nil, err - } - if next.ID == entry.ID { - return nil, ErrBadLink{ - entry.Name(), - "recursive link", - } - } - entry = next - } else { + for i := 0; i < limit; i++ { + if !entry.IsLink() { break } + next, err := entry.FollowLink() + if err != nil { + return nil, err + } + if next.ID == entry.ID { + return nil, ErrSymlinkUnresolved{entry.Name(), "recursive link"} + } + entry = next } if entry.IsLink() { - return nil, ErrBadLink{ - te.Name(), - "too many levels of symbolic links", - } + return nil, ErrSymlinkUnresolved{te.Name(), "too many levels of symbolic links"} } return entry, nil } diff --git a/modules/git/tree_entry_mode.go b/modules/git/tree_entry_mode.go index ec4487549d..1193bec4f1 100644 --- a/modules/git/tree_entry_mode.go +++ b/modules/git/tree_entry_mode.go @@ -17,16 +17,12 @@ const ( // EntryModeNoEntry is possible if the file was added or removed in a commit. In the case of // added the base commit will not have the file in its tree so a mode of 0o000000 is used. EntryModeNoEntry EntryMode = 0o000000 - // EntryModeBlob - EntryModeBlob EntryMode = 0o100644 - // EntryModeExec - EntryModeExec EntryMode = 0o100755 - // EntryModeSymlink + + EntryModeBlob EntryMode = 0o100644 + EntryModeExec EntryMode = 0o100755 EntryModeSymlink EntryMode = 0o120000 - // EntryModeCommit - EntryModeCommit EntryMode = 0o160000 - // EntryModeTree - EntryModeTree EntryMode = 0o040000 + EntryModeCommit EntryMode = 0o160000 + EntryModeTree EntryMode = 0o040000 ) // String converts an EntryMode to a string @@ -34,12 +30,6 @@ func (e EntryMode) String() string { return strconv.FormatInt(int64(e), 8) } -// ToEntryMode converts a string to an EntryMode -func ToEntryMode(value string) EntryMode { - v, _ := strconv.ParseInt(value, 8, 32) - return EntryMode(v) -} - func ParseEntryMode(mode string) (EntryMode, error) { switch mode { case "000000": diff --git a/modules/git/tree_test.go b/modules/git/tree_test.go index 5fee64b038..61e5482538 100644 --- a/modules/git/tree_test.go +++ b/modules/git/tree_test.go @@ -33,10 +33,10 @@ func Test_GetTreePathLatestCommit(t *testing.T) { commitID, err := repo.GetBranchCommitID("master") assert.NoError(t, err) - assert.EqualValues(t, "544d8f7a3b15927cddf2299b4b562d6ebd71b6a7", commitID) + assert.Equal(t, "544d8f7a3b15927cddf2299b4b562d6ebd71b6a7", commitID) commit, err := repo.GetTreePathLatestCommit("master", "blame.txt") assert.NoError(t, err) assert.NotNil(t, commit) - assert.EqualValues(t, "45fb6cbc12f970b04eacd5cd4165edd11c8d7376", commit.ID.String()) + assert.Equal(t, "45fb6cbc12f970b04eacd5cd4165edd11c8d7376", commit.ID.String()) } diff --git a/modules/git/url/url_test.go b/modules/git/url/url_test.go index 681da564f9..6655c20be3 100644 --- a/modules/git/url/url_test.go +++ b/modules/git/url/url_test.go @@ -165,8 +165,8 @@ func TestParseGitURLs(t *testing.T) { t.Run(kase.kase, func(t *testing.T) { u, err := ParseGitURL(kase.kase) assert.NoError(t, err) - assert.EqualValues(t, kase.expected.extraMark, u.extraMark) - assert.EqualValues(t, *kase.expected, *u) + assert.Equal(t, kase.expected.extraMark, u.extraMark) + assert.Equal(t, *kase.expected, *u) }) } } diff --git a/modules/gitrepo/branch.go b/modules/gitrepo/branch.go index 25ea5abfca..d7857819e4 100644 --- a/modules/gitrepo/branch.go +++ b/modules/gitrepo/branch.go @@ -11,14 +11,14 @@ import ( // GetBranchesByPath returns a branch by its path // if limit = 0 it will not limit -func GetBranchesByPath(ctx context.Context, repo Repository, skip, limit int) ([]*git.Branch, int, error) { +func GetBranchesByPath(ctx context.Context, repo Repository, skip, limit int) ([]string, int, error) { gitRepo, err := OpenRepository(ctx, repo) if err != nil { return nil, 0, err } defer gitRepo.Close() - return gitRepo.GetBranches(skip, limit) + return gitRepo.GetBranchNames(skip, limit) } func GetBranchCommitID(ctx context.Context, repo Repository, branch string) (string, error) { diff --git a/modules/globallock/redis_locker.go b/modules/globallock/redis_locker.go index 34ed9e389b..45dc769fd4 100644 --- a/modules/globallock/redis_locker.go +++ b/modules/globallock/redis_locker.go @@ -6,7 +6,6 @@ package globallock import ( "context" "errors" - "fmt" "sync" "sync/atomic" "time" @@ -78,7 +77,7 @@ func (l *redisLocker) Close() error { func (l *redisLocker) lock(ctx context.Context, key string, tries int) (ReleaseFunc, error) { if l.closed.Load() { - return func() {}, fmt.Errorf("locker is closed") + return func() {}, errors.New("locker is closed") } options := []redsync.Option{ diff --git a/modules/graceful/releasereopen/releasereopen_test.go b/modules/graceful/releasereopen/releasereopen_test.go index 0e8b48257d..46e67c2046 100644 --- a/modules/graceful/releasereopen/releasereopen_test.go +++ b/modules/graceful/releasereopen/releasereopen_test.go @@ -30,14 +30,14 @@ func TestManager(t *testing.T) { _ = m.Register(t3) assert.NoError(t, m.ReleaseReopen()) - assert.EqualValues(t, 1, t1.count) - assert.EqualValues(t, 1, t2.count) - assert.EqualValues(t, 1, t3.count) + assert.Equal(t, 1, t1.count) + assert.Equal(t, 1, t2.count) + assert.Equal(t, 1, t3.count) c2() assert.NoError(t, m.ReleaseReopen()) - assert.EqualValues(t, 2, t1.count) - assert.EqualValues(t, 1, t2.count) - assert.EqualValues(t, 2, t3.count) + assert.Equal(t, 2, t1.count) + assert.Equal(t, 1, t2.count) + assert.Equal(t, 2, t3.count) } diff --git a/modules/highlight/highlight_test.go b/modules/highlight/highlight_test.go index 659688bd0f..b36de98c5c 100644 --- a/modules/highlight/highlight_test.go +++ b/modules/highlight/highlight_test.go @@ -114,7 +114,7 @@ c=2 t.Run(tt.name, func(t *testing.T) { out, lexerName, err := File(tt.name, "", []byte(tt.code)) assert.NoError(t, err) - assert.EqualValues(t, tt.want, out) + assert.Equal(t, tt.want, out) assert.Equal(t, tt.lexerName, lexerName) }) } @@ -177,7 +177,7 @@ c=2`), for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { out := PlainText([]byte(tt.code)) - assert.EqualValues(t, tt.want, out) + assert.Equal(t, tt.want, out) }) } } diff --git a/modules/httplib/request.go b/modules/httplib/request.go index 5e40922896..49ea6f4b73 100644 --- a/modules/httplib/request.go +++ b/modules/httplib/request.go @@ -108,7 +108,7 @@ func (r *Request) Body(data any) *Request { switch t := data.(type) { case nil: // do nothing case string: - bf := bytes.NewBufferString(t) + bf := strings.NewReader(t) r.req.Body = io.NopCloser(bf) r.req.ContentLength = int64(len(t)) case []byte: @@ -143,13 +143,13 @@ func (r *Request) getResponse() (*http.Response, error) { paramBody = paramBody[0 : len(paramBody)-1] } - if r.req.Method == "GET" && len(paramBody) > 0 { + if r.req.Method == http.MethodGet && len(paramBody) > 0 { if strings.Contains(r.url, "?") { r.url += "&" + paramBody } else { r.url = r.url + "?" + paramBody } - } else if r.req.Method == "POST" && r.req.Body == nil && len(paramBody) > 0 { + } else if r.req.Method == http.MethodPost && r.req.Body == nil && len(paramBody) > 0 { r.Header("Content-Type", "application/x-www-form-urlencoded") r.Body(paramBody) // string } diff --git a/modules/httplib/serve_test.go b/modules/httplib/serve_test.go index 06c95bc594..78b88c9b5f 100644 --- a/modules/httplib/serve_test.go +++ b/modules/httplib/serve_test.go @@ -4,11 +4,11 @@ package httplib import ( - "fmt" "net/http" "net/http/httptest" "net/url" "os" + "strconv" "strings" "testing" @@ -23,14 +23,14 @@ func TestServeContentByReader(t *testing.T) { _, rangeStr, _ := strings.Cut(t.Name(), "_range_") r := &http.Request{Header: http.Header{}, Form: url.Values{}} if rangeStr != "" { - r.Header.Set("Range", fmt.Sprintf("bytes=%s", rangeStr)) + r.Header.Set("Range", "bytes="+rangeStr) } reader := strings.NewReader(data) w := httptest.NewRecorder() ServeContentByReader(r, w, int64(len(data)), reader, &ServeHeaderOptions{}) assert.Equal(t, expectedStatusCode, w.Code) if expectedStatusCode == http.StatusPartialContent || expectedStatusCode == http.StatusOK { - assert.Equal(t, fmt.Sprint(len(expectedContent)), w.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(expectedContent)), w.Header().Get("Content-Length")) assert.Equal(t, expectedContent, w.Body.String()) } } @@ -68,7 +68,7 @@ func TestServeContentByReadSeeker(t *testing.T) { _, rangeStr, _ := strings.Cut(t.Name(), "_range_") r := &http.Request{Header: http.Header{}, Form: url.Values{}} if rangeStr != "" { - r.Header.Set("Range", fmt.Sprintf("bytes=%s", rangeStr)) + r.Header.Set("Range", "bytes="+rangeStr) } seekReader, err := os.OpenFile(tmpFile, os.O_RDONLY, 0o644) @@ -79,7 +79,7 @@ func TestServeContentByReadSeeker(t *testing.T) { ServeContentByReadSeeker(r, w, nil, seekReader, &ServeHeaderOptions{}) assert.Equal(t, expectedStatusCode, w.Code) if expectedStatusCode == http.StatusPartialContent || expectedStatusCode == http.StatusOK { - assert.Equal(t, fmt.Sprint(len(expectedContent)), w.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(expectedContent)), w.Header().Get("Content-Length")) assert.Equal(t, expectedContent, w.Body.String()) } } diff --git a/modules/indexer/code/bleve/token/path/path.go b/modules/indexer/code/bleve/token/path/path.go index 107e0da109..19f4b5bb5e 100644 --- a/modules/indexer/code/bleve/token/path/path.go +++ b/modules/indexer/code/bleve/token/path/path.go @@ -53,11 +53,11 @@ func generatePathTokens(input analysis.TokenStream, reversed bool) analysis.Toke for i := 0; i < len(input); i++ { var sb strings.Builder - sb.WriteString(string(input[0].Term)) + sb.Write(input[0].Term) for j := 1; j < i; j++ { sb.WriteString("/") - sb.WriteString(string(input[j].Term)) + sb.Write(input[j].Term) } term := sb.String() diff --git a/modules/indexer/code/elasticsearch/elasticsearch_test.go b/modules/indexer/code/elasticsearch/elasticsearch_test.go index a6d2af92b2..e8f1f202ce 100644 --- a/modules/indexer/code/elasticsearch/elasticsearch_test.go +++ b/modules/indexer/code/elasticsearch/elasticsearch_test.go @@ -11,6 +11,6 @@ import ( func TestIndexPos(t *testing.T) { startIdx, endIdx := contentMatchIndexPos("test index start and end", "start", "end") - assert.EqualValues(t, 11, startIdx) - assert.EqualValues(t, 15, endIdx) + assert.Equal(t, 11, startIdx) + assert.Equal(t, 15, endIdx) } diff --git a/modules/indexer/code/indexer_test.go b/modules/indexer/code/indexer_test.go index 1d9bf99d40..78fea22f10 100644 --- a/modules/indexer/code/indexer_test.go +++ b/modules/indexer/code/indexer_test.go @@ -310,7 +310,7 @@ func TestESIndexAndSearch(t *testing.T) { if indexer != nil { indexer.Close() } - assert.FailNow(t, "Unable to init ES indexer Error: %v", err) + require.NoError(t, err, "Unable to init ES indexer") } defer indexer.Close() diff --git a/modules/indexer/code/internal/indexer.go b/modules/indexer/code/internal/indexer.go index 6c9a8af635..d58b028124 100644 --- a/modules/indexer/code/internal/indexer.go +++ b/modules/indexer/code/internal/indexer.go @@ -5,7 +5,7 @@ package internal import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" @@ -48,13 +48,13 @@ func (d *dummyIndexer) SupportedSearchModes() []indexer.SearchMode { } func (d *dummyIndexer) Index(ctx context.Context, repo *repo_model.Repository, sha string, changes *RepoChanges) error { - return fmt.Errorf("indexer is not ready") + return errors.New("indexer is not ready") } func (d *dummyIndexer) Delete(ctx context.Context, repoID int64) error { - return fmt.Errorf("indexer is not ready") + return errors.New("indexer is not ready") } func (d *dummyIndexer) Search(ctx context.Context, opts *SearchOptions) (int64, []*SearchResult, []*SearchResultLanguages, error) { - return 0, nil, nil, fmt.Errorf("indexer is not ready") + return 0, nil, nil, errors.New("indexer is not ready") } diff --git a/modules/indexer/internal/bleve/indexer.go b/modules/indexer/internal/bleve/indexer.go index 01e53ca636..9d1e24a874 100644 --- a/modules/indexer/internal/bleve/indexer.go +++ b/modules/indexer/internal/bleve/indexer.go @@ -5,7 +5,7 @@ package bleve import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/modules/indexer/internal" "code.gitea.io/gitea/modules/log" @@ -39,11 +39,11 @@ func NewIndexer(indexDir string, version int, mappingGetter func() (mapping.Inde // Init initializes the indexer func (i *Indexer) Init(_ context.Context) (bool, error) { if i == nil { - return false, fmt.Errorf("cannot init nil indexer") + return false, errors.New("cannot init nil indexer") } if i.Indexer != nil { - return false, fmt.Errorf("indexer is already initialized") + return false, errors.New("indexer is already initialized") } indexer, version, err := openIndexer(i.indexDir, i.version) @@ -83,10 +83,10 @@ func (i *Indexer) Init(_ context.Context) (bool, error) { // Ping checks if the indexer is available func (i *Indexer) Ping(_ context.Context) error { if i == nil { - return fmt.Errorf("cannot ping nil indexer") + return errors.New("cannot ping nil indexer") } if i.Indexer == nil { - return fmt.Errorf("indexer is not initialized") + return errors.New("indexer is not initialized") } return nil } diff --git a/modules/indexer/internal/elasticsearch/indexer.go b/modules/indexer/internal/elasticsearch/indexer.go index 395eea3bce..265ce26585 100644 --- a/modules/indexer/internal/elasticsearch/indexer.go +++ b/modules/indexer/internal/elasticsearch/indexer.go @@ -5,6 +5,7 @@ package elasticsearch import ( "context" + "errors" "fmt" "code.gitea.io/gitea/modules/indexer/internal" @@ -36,10 +37,10 @@ func NewIndexer(url, indexName string, version int, mapping string) *Indexer { // Init initializes the indexer func (i *Indexer) Init(ctx context.Context) (bool, error) { if i == nil { - return false, fmt.Errorf("cannot init nil indexer") + return false, errors.New("cannot init nil indexer") } if i.Client != nil { - return false, fmt.Errorf("indexer is already initialized") + return false, errors.New("indexer is already initialized") } client, err := i.initClient() @@ -66,10 +67,10 @@ func (i *Indexer) Init(ctx context.Context) (bool, error) { // Ping checks if the indexer is available func (i *Indexer) Ping(ctx context.Context) error { if i == nil { - return fmt.Errorf("cannot ping nil indexer") + return errors.New("cannot ping nil indexer") } if i.Client == nil { - return fmt.Errorf("indexer is not initialized") + return errors.New("indexer is not initialized") } resp, err := i.Client.ClusterHealth().Do(ctx) diff --git a/modules/indexer/internal/indexer.go b/modules/indexer/internal/indexer.go index c7f356da1e..3442bbaff2 100644 --- a/modules/indexer/internal/indexer.go +++ b/modules/indexer/internal/indexer.go @@ -5,7 +5,7 @@ package internal import ( "context" - "fmt" + "errors" ) // Indexer defines an basic indexer interface @@ -27,11 +27,11 @@ func NewDummyIndexer() Indexer { type dummyIndexer struct{} func (d *dummyIndexer) Init(ctx context.Context) (bool, error) { - return false, fmt.Errorf("indexer is not ready") + return false, errors.New("indexer is not ready") } func (d *dummyIndexer) Ping(ctx context.Context) error { - return fmt.Errorf("indexer is not ready") + return errors.New("indexer is not ready") } func (d *dummyIndexer) Close() {} diff --git a/modules/indexer/internal/meilisearch/indexer.go b/modules/indexer/internal/meilisearch/indexer.go index 01bb49bbfc..65db75bb55 100644 --- a/modules/indexer/internal/meilisearch/indexer.go +++ b/modules/indexer/internal/meilisearch/indexer.go @@ -5,6 +5,7 @@ package meilisearch import ( "context" + "errors" "fmt" "github.com/meilisearch/meilisearch-go" @@ -33,11 +34,11 @@ func NewIndexer(url, apiKey, indexName string, version int, settings *meilisearc // Init initializes the indexer func (i *Indexer) Init(_ context.Context) (bool, error) { if i == nil { - return false, fmt.Errorf("cannot init nil indexer") + return false, errors.New("cannot init nil indexer") } if i.Client != nil { - return false, fmt.Errorf("indexer is already initialized") + return false, errors.New("indexer is already initialized") } i.Client = meilisearch.New(i.url, meilisearch.WithAPIKey(i.apiKey)) @@ -62,10 +63,10 @@ func (i *Indexer) Init(_ context.Context) (bool, error) { // Ping checks if the indexer is available func (i *Indexer) Ping(ctx context.Context) error { if i == nil { - return fmt.Errorf("cannot ping nil indexer") + return errors.New("cannot ping nil indexer") } if i.Client == nil { - return fmt.Errorf("indexer is not initialized") + return errors.New("indexer is not initialized") } resp, err := i.Client.Health() if err != nil { diff --git a/modules/indexer/issues/elasticsearch/elasticsearch.go b/modules/indexer/issues/elasticsearch/elasticsearch.go index e3b1b17059..9d627466ef 100644 --- a/modules/indexer/issues/elasticsearch/elasticsearch.go +++ b/modules/indexer/issues/elasticsearch/elasticsearch.go @@ -5,7 +5,6 @@ package elasticsearch import ( "context" - "fmt" "strconv" "strings" @@ -96,7 +95,7 @@ func (b *Indexer) Index(ctx context.Context, issues ...*internal.IndexerData) er issue := issues[0] _, err := b.inner.Client.Index(). Index(b.inner.VersionedIndexName()). - Id(fmt.Sprintf("%d", issue.ID)). + Id(strconv.FormatInt(issue.ID, 10)). BodyJson(issue). Do(ctx) return err @@ -107,7 +106,7 @@ func (b *Indexer) Index(ctx context.Context, issues ...*internal.IndexerData) er reqs = append(reqs, elastic.NewBulkIndexRequest(). Index(b.inner.VersionedIndexName()). - Id(fmt.Sprintf("%d", issue.ID)). + Id(strconv.FormatInt(issue.ID, 10)). Doc(issue), ) } @@ -126,7 +125,7 @@ func (b *Indexer) Delete(ctx context.Context, ids ...int64) error { } else if len(ids) == 1 { _, err := b.inner.Client.Delete(). Index(b.inner.VersionedIndexName()). - Id(fmt.Sprintf("%d", ids[0])). + Id(strconv.FormatInt(ids[0], 10)). Do(ctx) return err } @@ -136,7 +135,7 @@ func (b *Indexer) Delete(ctx context.Context, ids ...int64) error { reqs = append(reqs, elastic.NewBulkDeleteRequest(). Index(b.inner.VersionedIndexName()). - Id(fmt.Sprintf("%d", id)), + Id(strconv.FormatInt(id, 10)), ) } diff --git a/modules/indexer/issues/internal/indexer.go b/modules/indexer/issues/internal/indexer.go index 415f442d0c..59c6f48485 100644 --- a/modules/indexer/issues/internal/indexer.go +++ b/modules/indexer/issues/internal/indexer.go @@ -5,7 +5,7 @@ package internal import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/modules/indexer" "code.gitea.io/gitea/modules/indexer/internal" @@ -36,13 +36,13 @@ func (d *dummyIndexer) SupportedSearchModes() []indexer.SearchMode { } func (d *dummyIndexer) Index(_ context.Context, _ ...*IndexerData) error { - return fmt.Errorf("indexer is not ready") + return errors.New("indexer is not ready") } func (d *dummyIndexer) Delete(_ context.Context, _ ...int64) error { - return fmt.Errorf("indexer is not ready") + return errors.New("indexer is not ready") } func (d *dummyIndexer) Search(_ context.Context, _ *SearchOptions) (*SearchResult, error) { - return nil, fmt.Errorf("indexer is not ready") + return nil, errors.New("indexer is not ready") } diff --git a/modules/indexer/issues/internal/tests/tests.go b/modules/indexer/issues/internal/tests/tests.go index 6e92c7885c..a42ec9a2bc 100644 --- a/modules/indexer/issues/internal/tests/tests.go +++ b/modules/indexer/issues/internal/tests/tests.go @@ -93,7 +93,7 @@ var cases = []*testIndexerCase{ Name: "default", SearchOptions: &internal.SearchOptions{}, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) }, }, @@ -526,7 +526,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByCreatedDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -542,7 +542,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByUpdatedDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -558,7 +558,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByCommentsDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -574,7 +574,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByDeadlineDesc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -590,7 +590,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByCreatedAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -606,7 +606,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByUpdatedAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -622,7 +622,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByCommentsAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { @@ -638,7 +638,7 @@ var cases = []*testIndexerCase{ SortBy: internal.SortByDeadlineAsc, }, Expected: func(t *testing.T, data map[int64]*internal.IndexerData, result *internal.SearchResult) { - assert.Equal(t, len(data), len(result.Hits)) + assert.Len(t, result.Hits, len(data)) assert.Equal(t, len(data), int(result.Total)) for i, v := range result.Hits { if i < len(result.Hits)-1 { diff --git a/modules/indexer/issues/meilisearch/meilisearch_test.go b/modules/indexer/issues/meilisearch/meilisearch_test.go index a3a332554a..2fea4004cb 100644 --- a/modules/indexer/issues/meilisearch/meilisearch_test.go +++ b/modules/indexer/issues/meilisearch/meilisearch_test.go @@ -74,13 +74,13 @@ func TestConvertHits(t *testing.T) { } hits, err := convertHits(validResponse) assert.NoError(t, err) - assert.EqualValues(t, []internal.Match{{ID: 11}, {ID: 22}, {ID: 33}}, hits) + assert.Equal(t, []internal.Match{{ID: 11}, {ID: 22}, {ID: 33}}, hits) } func TestDoubleQuoteKeyword(t *testing.T) { - assert.EqualValues(t, "", doubleQuoteKeyword("")) - assert.EqualValues(t, `"a" "b" "c"`, doubleQuoteKeyword("a b c")) - assert.EqualValues(t, `"a" "d" "g"`, doubleQuoteKeyword("a d g")) - assert.EqualValues(t, `"a" "d" "g"`, doubleQuoteKeyword("a d g")) - assert.EqualValues(t, `"a" "d" "g"`, doubleQuoteKeyword(`a "" "d" """g`)) + assert.Empty(t, doubleQuoteKeyword("")) + assert.Equal(t, `"a" "b" "c"`, doubleQuoteKeyword("a b c")) + assert.Equal(t, `"a" "d" "g"`, doubleQuoteKeyword("a d g")) + assert.Equal(t, `"a" "d" "g"`, doubleQuoteKeyword("a d g")) + assert.Equal(t, `"a" "d" "g"`, doubleQuoteKeyword(`a "" "d" """g`)) } diff --git a/modules/indexer/stats/queue.go b/modules/indexer/stats/queue.go index d002bd57cf..69cde321d8 100644 --- a/modules/indexer/stats/queue.go +++ b/modules/indexer/stats/queue.go @@ -4,7 +4,7 @@ package stats import ( - "fmt" + "errors" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/graceful" @@ -31,7 +31,7 @@ func handler(items ...int64) []int64 { func initStatsQueue() error { statsQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "repo_stats_update", handler) if statsQueue == nil { - return fmt.Errorf("unable to create repo_stats_update queue") + return errors.New("unable to create repo_stats_update queue") } go graceful.GetManager().RunWithCancel(statsQueue) return nil diff --git a/modules/issue/template/template.go b/modules/issue/template/template.go index a2b9d6b33e..84ae90e4ed 100644 --- a/modules/issue/template/template.go +++ b/modules/issue/template/template.go @@ -4,6 +4,7 @@ package template import ( + "errors" "fmt" "net/url" "regexp" @@ -31,17 +32,17 @@ func Validate(template *api.IssueTemplate) error { func validateMetadata(template *api.IssueTemplate) error { if strings.TrimSpace(template.Name) == "" { - return fmt.Errorf("'name' is required") + return errors.New("'name' is required") } if strings.TrimSpace(template.About) == "" { - return fmt.Errorf("'about' is required") + return errors.New("'about' is required") } return nil } func validateYaml(template *api.IssueTemplate) error { if len(template.Fields) == 0 { - return fmt.Errorf("'body' is required") + return errors.New("'body' is required") } ids := make(container.Set[string]) for idx, field := range template.Fields { @@ -401,7 +402,7 @@ func (f *valuedField) Render() string { } func (f *valuedField) Value() string { - return strings.TrimSpace(f.Get(fmt.Sprintf("form-field-%s", f.ID))) + return strings.TrimSpace(f.Get("form-field-" + f.ID)) } func (f *valuedField) Options() []*valuedOption { @@ -444,7 +445,7 @@ func (o *valuedOption) Label() string { func (o *valuedOption) IsChecked() bool { switch o.field.Type { case api.IssueFormFieldTypeDropdown: - checks := strings.Split(o.field.Get(fmt.Sprintf("form-field-%s", o.field.ID)), ",") + checks := strings.Split(o.field.Get("form-field-"+o.field.ID), ",") idx := strconv.Itoa(o.index) for _, v := range checks { if v == idx { diff --git a/modules/issue/template/template_test.go b/modules/issue/template/template_test.go index 575e23def9..7fec9431b6 100644 --- a/modules/issue/template/template_test.go +++ b/modules/issue/template/template_test.go @@ -904,7 +904,7 @@ Option 1 of dropdown, Option 2 of dropdown t.Fatal(err) } if got := RenderToMarkdown(template, tt.args.values); got != tt.want { - assert.EqualValues(t, tt.want, got) + assert.Equal(t, tt.want, got) } }) } diff --git a/modules/lfs/http_client.go b/modules/lfs/http_client.go index 0a27fb0c86..4b51193846 100644 --- a/modules/lfs/http_client.go +++ b/modules/lfs/http_client.go @@ -70,7 +70,7 @@ func (c *HTTPClient) transferNames() []string { func (c *HTTPClient) batch(ctx context.Context, operation string, objects []Pointer) (*BatchResponse, error) { log.Trace("BATCH operation with objects: %v", objects) - url := fmt.Sprintf("%s/objects/batch", c.endpoint) + url := c.endpoint + "/objects/batch" // Original: In some lfs server implementations, they require the ref attribute. #32838 // `ref` is an "optional object describing the server ref that the objects belong to" diff --git a/modules/lfs/http_client_test.go b/modules/lfs/http_client_test.go index 7869c0a21a..179bcdb29a 100644 --- a/modules/lfs/http_client_test.go +++ b/modules/lfs/http_client_test.go @@ -31,7 +31,7 @@ func (a *DummyTransferAdapter) Name() string { } func (a *DummyTransferAdapter) Download(ctx context.Context, l *Link) (io.ReadCloser, error) { - return io.NopCloser(bytes.NewBufferString("dummy")), nil + return io.NopCloser(strings.NewReader("dummy")), nil } func (a *DummyTransferAdapter) Upload(ctx context.Context, l *Link, p Pointer, r io.Reader) error { @@ -49,7 +49,7 @@ func lfsTestRoundtripHandler(req *http.Request) *http.Response { if strings.Contains(url, "status-not-ok") { return &http.Response{StatusCode: http.StatusBadRequest} } else if strings.Contains(url, "invalid-json-response") { - return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString("invalid json"))} + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader("invalid json"))} } else if strings.Contains(url, "valid-batch-request-download") { batchResponse = &BatchResponse{ Transfer: "dummy", diff --git a/modules/lfs/transferadapter_test.go b/modules/lfs/transferadapter_test.go index 8bbd45771a..ef72d76db4 100644 --- a/modules/lfs/transferadapter_test.go +++ b/modules/lfs/transferadapter_test.go @@ -32,7 +32,7 @@ func TestBasicTransferAdapter(t *testing.T) { if strings.Contains(url, "download-request") { assert.Equal(t, "GET", req.Method) - return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(bytes.NewBufferString("dummy"))} + return &http.Response{StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader("dummy"))} } else if strings.Contains(url, "upload-request") { assert.Equal(t, "PUT", req.Method) assert.Equal(t, "application/octet-stream", req.Header.Get("Content-Type")) @@ -126,7 +126,7 @@ func TestBasicTransferAdapter(t *testing.T) { } for n, c := range cases { - err := a.Upload(t.Context(), c.link, p, bytes.NewBufferString("dummy")) + err := a.Upload(t.Context(), c.link, p, strings.NewReader("dummy")) if len(c.expectederror) > 0 { assert.Contains(t, err.Error(), c.expectederror, "case %d: '%s' should contain '%s'", n, err.Error(), c.expectederror) } else { diff --git a/modules/lfstransfer/backend/backend.go b/modules/lfstransfer/backend/backend.go index 1328d93a48..dd4108ea56 100644 --- a/modules/lfstransfer/backend/backend.go +++ b/modules/lfstransfer/backend/backend.go @@ -47,7 +47,7 @@ func New(ctx context.Context, repo, op, token string, logger transfer.Logger) (t return nil, err } server = server.JoinPath("api/internal/repo", repo, "info/lfs") - return &GiteaBackend{ctx: ctx, server: server, op: op, authToken: token, internalAuth: fmt.Sprintf("Bearer %s", setting.InternalToken), logger: logger}, nil + return &GiteaBackend{ctx: ctx, server: server, op: op, authToken: token, internalAuth: "Bearer " + setting.InternalToken, logger: logger}, nil } // Batch implements transfer.Backend diff --git a/modules/lfstransfer/backend/lock.go b/modules/lfstransfer/backend/lock.go index 639f8b184e..2c3c16a9bb 100644 --- a/modules/lfstransfer/backend/lock.go +++ b/modules/lfstransfer/backend/lock.go @@ -5,6 +5,7 @@ package backend import ( "context" + "errors" "fmt" "io" "net/http" @@ -74,7 +75,7 @@ func (g *giteaLockBackend) Create(path, refname string) (transfer.Lock, error) { if respBody.Lock == nil { g.logger.Log("api returned nil lock") - return nil, fmt.Errorf("api returned nil lock") + return nil, errors.New("api returned nil lock") } respLock := respBody.Lock owner := userUnknown @@ -263,7 +264,7 @@ func (g *giteaLock) CurrentUser() (string, error) { // AsLockSpec implements transfer.Lock func (g *giteaLock) AsLockSpec(ownerID bool) ([]string, error) { msgs := []string{ - fmt.Sprintf("lock %s", g.ID()), + "lock " + g.ID(), fmt.Sprintf("path %s %s", g.ID(), g.Path()), fmt.Sprintf("locked-at %s %s", g.ID(), g.FormattedTimestamp()), fmt.Sprintf("ownername %s %s", g.ID(), g.OwnerName()), @@ -285,9 +286,9 @@ func (g *giteaLock) AsLockSpec(ownerID bool) ([]string, error) { // AsArguments implements transfer.Lock func (g *giteaLock) AsArguments() []string { return []string{ - fmt.Sprintf("id=%s", g.ID()), - fmt.Sprintf("path=%s", g.Path()), - fmt.Sprintf("locked-at=%s", g.FormattedTimestamp()), - fmt.Sprintf("ownername=%s", g.OwnerName()), + "id=" + g.ID(), + "path=" + g.Path(), + "locked-at=" + g.FormattedTimestamp(), + "ownername=" + g.OwnerName(), } } diff --git a/modules/log/flags_test.go b/modules/log/flags_test.go index 03972a9fb0..6eb65d8114 100644 --- a/modules/log/flags_test.go +++ b/modules/log/flags_test.go @@ -12,19 +12,19 @@ import ( ) func TestFlags(t *testing.T) { - assert.EqualValues(t, Ldefault, Flags{}.Bits()) + assert.Equal(t, Ldefault, Flags{}.Bits()) assert.EqualValues(t, 0, FlagsFromString("").Bits()) - assert.EqualValues(t, Lgopid, FlagsFromString("", Lgopid).Bits()) + assert.Equal(t, Lgopid, FlagsFromString("", Lgopid).Bits()) assert.EqualValues(t, 0, FlagsFromString("none", Lgopid).Bits()) - assert.EqualValues(t, Ldate|Ltime, FlagsFromString("date,time", Lgopid).Bits()) + assert.Equal(t, Ldate|Ltime, FlagsFromString("date,time", Lgopid).Bits()) - assert.EqualValues(t, "stdflags", FlagsFromString("stdflags").String()) - assert.EqualValues(t, "medfile", FlagsFromString("medfile").String()) + assert.Equal(t, "stdflags", FlagsFromString("stdflags").String()) + assert.Equal(t, "medfile", FlagsFromString("medfile").String()) bs, err := json.Marshal(FlagsFromString("utc,level")) assert.NoError(t, err) - assert.EqualValues(t, `"level,utc"`, string(bs)) + assert.Equal(t, `"level,utc"`, string(bs)) var flags Flags assert.NoError(t, json.Unmarshal(bs, &flags)) - assert.EqualValues(t, LUTC|Llevel, flags.Bits()) + assert.Equal(t, LUTC|Llevel, flags.Bits()) } diff --git a/modules/log/logger_test.go b/modules/log/logger_test.go index 9f604815f6..a74139dc51 100644 --- a/modules/log/logger_test.go +++ b/modules/log/logger_test.go @@ -57,16 +57,16 @@ func TestLogger(t *testing.T) { dump := logger.DumpWriters() assert.Empty(t, dump) - assert.EqualValues(t, NONE, logger.GetLevel()) + assert.Equal(t, NONE, logger.GetLevel()) assert.False(t, logger.IsEnabled()) w1 := newDummyWriter("dummy-1", DEBUG, 0) logger.AddWriters(w1) - assert.EqualValues(t, DEBUG, logger.GetLevel()) + assert.Equal(t, DEBUG, logger.GetLevel()) w2 := newDummyWriter("dummy-2", WARN, 200*time.Millisecond) logger.AddWriters(w2) - assert.EqualValues(t, DEBUG, logger.GetLevel()) + assert.Equal(t, DEBUG, logger.GetLevel()) dump = logger.DumpWriters() assert.Len(t, dump, 2) diff --git a/modules/markup/common/footnote.go b/modules/markup/common/footnote.go index 4406803694..9a4f18ed7f 100644 --- a/modules/markup/common/footnote.go +++ b/modules/markup/common/footnote.go @@ -53,7 +53,7 @@ type FootnoteLink struct { // Dump implements Node.Dump. func (n *FootnoteLink) Dump(source []byte, level int) { m := map[string]string{} - m["Index"] = fmt.Sprintf("%v", n.Index) + m["Index"] = strconv.Itoa(n.Index) m["Name"] = fmt.Sprintf("%v", n.Name) ast.DumpHelper(n, source, level, m, nil) } @@ -85,7 +85,7 @@ type FootnoteBackLink struct { // Dump implements Node.Dump. func (n *FootnoteBackLink) Dump(source []byte, level int) { m := map[string]string{} - m["Index"] = fmt.Sprintf("%v", n.Index) + m["Index"] = strconv.Itoa(n.Index) m["Name"] = fmt.Sprintf("%v", n.Name) ast.DumpHelper(n, source, level, m, nil) } @@ -151,7 +151,7 @@ type FootnoteList struct { // Dump implements Node.Dump. func (n *FootnoteList) Dump(source []byte, level int) { m := map[string]string{} - m["Count"] = fmt.Sprintf("%v", n.Count) + m["Count"] = strconv.Itoa(n.Count) ast.DumpHelper(n, source, level, m, nil) } diff --git a/modules/markup/console/console_test.go b/modules/markup/console/console_test.go index 040ec151f4..539f965ea1 100644 --- a/modules/markup/console/console_test.go +++ b/modules/markup/console/console_test.go @@ -25,6 +25,6 @@ func TestRenderConsole(t *testing.T) { err := render.Render(markup.NewRenderContext(t.Context()), strings.NewReader(k), &buf) assert.NoError(t, err) - assert.EqualValues(t, v, buf.String()) + assert.Equal(t, v, buf.String()) } } diff --git a/modules/markup/csv/csv_test.go b/modules/markup/csv/csv_test.go index b0b18ab467..fff7f0baca 100644 --- a/modules/markup/csv/csv_test.go +++ b/modules/markup/csv/csv_test.go @@ -25,6 +25,6 @@ func TestRenderCSV(t *testing.T) { var buf strings.Builder err := render.Render(markup.NewRenderContext(t.Context()), strings.NewReader(k), &buf) assert.NoError(t, err) - assert.EqualValues(t, v, buf.String()) + assert.Equal(t, v, buf.String()) } } diff --git a/modules/markup/external/external.go b/modules/markup/external/external.go index 03242e569e..f708457853 100644 --- a/modules/markup/external/external.go +++ b/modules/markup/external/external.go @@ -77,14 +77,14 @@ func envMark(envName string) string { // Render renders the data of the document to HTML via the external tool. func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error { - var ( - command = strings.NewReplacer( - envMark("GITEA_PREFIX_SRC"), ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault), - envMark("GITEA_PREFIX_RAW"), ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw), - ).Replace(p.Command) - commands = strings.Fields(command) - args = commands[1:] - ) + baseLinkSrc := ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault) + baseLinkRaw := ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw) + command := strings.NewReplacer( + envMark("GITEA_PREFIX_SRC"), baseLinkSrc, + envMark("GITEA_PREFIX_RAW"), baseLinkRaw, + ).Replace(p.Command) + commands := strings.Fields(command) + args := commands[1:] if p.IsInputFile { // write to temp file @@ -112,14 +112,14 @@ func (p *Renderer) Render(ctx *markup.RenderContext, input io.Reader, output io. args = append(args, f.Name()) } - processCtx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Render [%s] for %s", commands[0], ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault))) + processCtx, _, finished := process.GetManager().AddContext(ctx, fmt.Sprintf("Render [%s] for %s", commands[0], baseLinkSrc)) defer finished() cmd := exec.CommandContext(processCtx, commands[0], args...) cmd.Env = append( os.Environ(), - "GITEA_PREFIX_SRC="+ctx.RenderHelper.ResolveLink("", markup.LinkTypeDefault), - "GITEA_PREFIX_RAW="+ctx.RenderHelper.ResolveLink("", markup.LinkTypeRaw), + "GITEA_PREFIX_SRC="+baseLinkSrc, + "GITEA_PREFIX_RAW="+baseLinkRaw, ) if !p.IsInputFile { cmd.Stdin = input diff --git a/modules/markup/html.go b/modules/markup/html.go index 3aaf669c63..0e074cbcfa 100644 --- a/modules/markup/html.go +++ b/modules/markup/html.go @@ -32,7 +32,6 @@ type globalVarsType struct { comparePattern *regexp.Regexp fullURLPattern *regexp.Regexp emailRegex *regexp.Regexp - blackfridayExtRegex *regexp.Regexp emojiShortCodeRegex *regexp.Regexp issueFullPattern *regexp.Regexp filesChangedFullPattern *regexp.Regexp @@ -74,9 +73,6 @@ var globalVars = sync.OnceValue(func() *globalVarsType { // https://html.spec.whatwg.org/multipage/input.html#e-mail-state-(type%3Demail) v.emailRegex = regexp.MustCompile("(?:\\s|^|\\(|\\[)([a-zA-Z0-9.!#$%&'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9]{2,}(?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)+)(?:\\s|$|\\)|\\]|;|,|\\?|!|\\.(\\s|$))") - // blackfridayExtRegex is for blackfriday extensions create IDs like fn:user-content-footnote - v.blackfridayExtRegex = regexp.MustCompile(`[^:]*:user-content-`) - // emojiShortCodeRegex find emoji by alias like :smile: v.emojiShortCodeRegex = regexp.MustCompile(`:[-+\w]+:`) @@ -89,22 +85,18 @@ var globalVars = sync.OnceValue(func() *globalVarsType { // codePreviewPattern matches "http://domain/.../{owner}/{repo}/src/commit/{commit}/{filepath}#L10-L20" v.codePreviewPattern = regexp.MustCompile(`https?://\S+/([^\s/]+)/([^\s/]+)/src/commit/([0-9a-f]{7,64})(/\S+)#(L\d+(-L\d+)?)`) - v.tagCleaner = regexp.MustCompile(`<((?:/?\w+/\w+)|(?:/[\w ]+/)|(/?[hH][tT][mM][lL]\b)|(/?[hH][eE][aA][dD]\b))`) + // cleans: "`, then the next iteration will visit the "span" - // if we don't stop it, it will go into the TextNode again and create an infinite recursion - return node.NextSibling - } else if node.Data == "code" || node.Data == "pre" { - return node.NextSibling // ignore code and pre nodes - } else if node.Data == "img" { - return visitNodeImg(ctx, node) - } else if node.Data == "video" { - return visitNodeVideo(ctx, node) - } else if node.Data == "a" { - procs = emojiProcessors // Restrict text in links to emojis - } - for n := node.FirstChild; n != nil; { - n = visitNode(ctx, procs, n) - } - default: + processNodeAttrID(node) + + if isEmojiNode(node) { + // TextNode emoji will be converted to ``, then the next iteration will visit the "span" + // if we don't stop it, it will go into the TextNode again and create an infinite recursion + return node.NextSibling + } else if node.Data == "code" || node.Data == "pre" { + return node.NextSibling // ignore code and pre nodes + } else if node.Data == "img" { + return visitNodeImg(ctx, node) + } else if node.Data == "video" { + return visitNodeVideo(ctx, node) + } + + if node.Data == "a" { + processNodeA(ctx, node) + // only use emoji processors for the content in the "A" tag, + // because the content there is not processable, for example: the content is a commit id or a full URL. + procs = emojiProcessors + } + for n := node.FirstChild; n != nil; { + n = visitNode(ctx, procs, n) } return node.NextSibling } diff --git a/modules/markup/html_commit.go b/modules/markup/html_commit.go index aa1b7d034a..967c327f36 100644 --- a/modules/markup/html_commit.go +++ b/modules/markup/html_commit.go @@ -43,7 +43,6 @@ func createCodeLink(href, content, class string) *html.Node { code := &html.Node{ Type: html.ElementNode, Data: atom.Code.String(), - Attr: []html.Attribute{{Key: "class", Val: "nohighlight"}}, } code.AppendChild(text) @@ -189,7 +188,7 @@ func hashCurrentPatternProcessor(ctx *RenderContext, node *html.Node) { continue } - link := ctx.RenderHelper.ResolveLink(util.URLJoin(ctx.RenderOptions.Metas["user"], ctx.RenderOptions.Metas["repo"], "commit", hash), LinkTypeApp) + link := "/:root/" + util.URLJoin(ctx.RenderOptions.Metas["user"], ctx.RenderOptions.Metas["repo"], "commit", hash) replaceContent(node, m[2], m[3], createCodeLink(link, base.ShortSha(hash), "commit")) start = 0 node = node.NextSibling.NextSibling @@ -205,9 +204,9 @@ func commitCrossReferencePatternProcessor(ctx *RenderContext, node *html.Node) { return } - reftext := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha) - linkHref := ctx.RenderHelper.ResolveLink(util.URLJoin(ref.Owner, ref.Name, "commit", ref.CommitSha), LinkTypeApp) - link := createLink(ctx, linkHref, reftext, "commit") + refText := ref.Owner + "/" + ref.Name + "@" + base.ShortSha(ref.CommitSha) + linkHref := "/:root/" + util.URLJoin(ref.Owner, ref.Name, "commit", ref.CommitSha) + link := createLink(ctx, linkHref, refText, "commit") replaceContent(node, ref.RefLocation.Start, ref.RefLocation.End, link) node = node.NextSibling.NextSibling diff --git a/modules/markup/html_internal_test.go b/modules/markup/html_internal_test.go index 159d712955..467cc509d0 100644 --- a/modules/markup/html_internal_test.go +++ b/modules/markup/html_internal_test.go @@ -107,7 +107,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { isExternal := false if marker == "!" { path = "pulls" - prefix = "http://localhost:3000/someUser/someRepo/pulls/" + prefix = "/someUser/someRepo/pulls/" } else { path = "issues" prefix = "https://someurl.com/someUser/someRepo/" @@ -116,7 +116,7 @@ func TestRender_IssueIndexPattern2(t *testing.T) { links := make([]any, len(indices)) for i, index := range indices { - links[i] = numericIssueLink(util.URLJoin(TestRepoURL, path), "ref-issue", index, marker) + links[i] = numericIssueLink(util.URLJoin("/test-owner/test-repo", path), "ref-issue", index, marker) } expectedNil := fmt.Sprintf(expectedFmt, links...) testRenderIssueIndexPattern(t, s, expectedNil, NewTestRenderContext(TestAppURL, localMetas)) @@ -293,13 +293,13 @@ func TestRender_AutoLink(t *testing.T) { // render valid commit URLs tmp := util.URLJoin(TestRepoURL, "commit", "d8a994ef243349f321568f9e36d5c3f444b99cae") - test(tmp, "d8a994ef24") + test(tmp, "d8a994ef24") tmp += "#diff-2" - test(tmp, "d8a994ef24 (diff-2)") + test(tmp, "d8a994ef24 (diff-2)") // render other commit URLs tmp = "https://external-link.gitea.io/go-gitea/gitea/commit/d8a994ef243349f321568f9e36d5c3f444b99cae#diff-2" - test(tmp, "d8a994ef24 (diff-2)") + test(tmp, "d8a994ef24 (diff-2)") } func TestRender_FullIssueURLs(t *testing.T) { @@ -405,10 +405,10 @@ func TestRegExp_anySHA1Pattern(t *testing.T) { if v.CommitID == "" { assert.False(t, ok) } else { - assert.EqualValues(t, strings.TrimSuffix(k, "."), ret.FullURL) - assert.EqualValues(t, v.CommitID, ret.CommitID) - assert.EqualValues(t, v.SubPath, ret.SubPath) - assert.EqualValues(t, v.QueryHash, ret.QueryHash) + assert.Equal(t, strings.TrimSuffix(k, "."), ret.FullURL) + assert.Equal(t, v.CommitID, ret.CommitID) + assert.Equal(t, v.SubPath, ret.SubPath) + assert.Equal(t, v.QueryHash, ret.QueryHash) } } } diff --git a/modules/markup/html_issue.go b/modules/markup/html_issue.go index 7a6f33011a..85bec5db20 100644 --- a/modules/markup/html_issue.go +++ b/modules/markup/html_issue.go @@ -82,7 +82,7 @@ func createIssueLinkContentWithSummary(ctx *RenderContext, linkHref string, ref h, err := DefaultRenderHelperFuncs.RenderRepoIssueIconTitle(ctx, RenderIssueIconTitleOptions{ OwnerName: ref.Owner, RepoName: ref.Name, - LinkHref: linkHref, + LinkHref: ctx.RenderHelper.ResolveLink(linkHref, LinkTypeDefault), IssueIndex: issueIndex, }) if err != nil { @@ -162,7 +162,7 @@ func issueIndexPatternProcessor(ctx *RenderContext, node *html.Node) { issueOwner := util.Iif(ref.Owner == "", ctx.RenderOptions.Metas["user"], ref.Owner) issueRepo := util.Iif(ref.Owner == "", ctx.RenderOptions.Metas["repo"], ref.Name) issuePath := util.Iif(ref.IsPull, "pulls", "issues") - linkHref := ctx.RenderHelper.ResolveLink(util.URLJoin(issueOwner, issueRepo, issuePath, ref.Issue), LinkTypeApp) + linkHref := "/:root/" + util.URLJoin(issueOwner, issueRepo, issuePath, ref.Issue) // at the moment, only render the issue index in a full line (or simple line) as icon+title // otherwise it would be too noisy for "take #1 as an example" in a sentence diff --git a/modules/markup/html_issue_test.go b/modules/markup/html_issue_test.go index 8d189fbdf6..c68429641f 100644 --- a/modules/markup/html_issue_test.go +++ b/modules/markup/html_issue_test.go @@ -39,7 +39,7 @@ func TestRender_IssueList(t *testing.T) { t.Run("NormalIssueRef", func(t *testing.T) { test( "#12345", - `#12345`, + `#12345`, ) }) @@ -56,7 +56,7 @@ func TestRender_IssueList(t *testing.T) { test( "* foo #12345 bar", ` -foo #12345 bar +foo #12345 bar `, ) }) diff --git a/modules/markup/html_link.go b/modules/markup/html_link.go index 0e7a988d36..1ea0b14028 100644 --- a/modules/markup/html_link.go +++ b/modules/markup/html_link.go @@ -125,7 +125,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) { } } if image { - link = ctx.RenderHelper.ResolveLink(link, LinkTypeMedia) title := props["title"] if title == "" { title = props["alt"] @@ -151,7 +150,6 @@ func shortLinkProcessor(ctx *RenderContext, node *html.Node) { childNode.Attr = childNode.Attr[:2] } } else { - link = ctx.RenderHelper.ResolveLink(link, LinkTypeDefault) childNode.Type = html.TextNode childNode.Data = name } diff --git a/modules/markup/html_mention.go b/modules/markup/html_mention.go index fffa12e7b7..f97c034cf3 100644 --- a/modules/markup/html_mention.go +++ b/modules/markup/html_mention.go @@ -33,7 +33,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { if ok && strings.Contains(mention, "/") { mentionOrgAndTeam := strings.Split(mention, "/") if mentionOrgAndTeam[0][1:] == ctx.RenderOptions.Metas["org"] && strings.Contains(teams, ","+strings.ToLower(mentionOrgAndTeam[1])+",") { - link := ctx.RenderHelper.ResolveLink(util.URLJoin("org", ctx.RenderOptions.Metas["org"], "teams", mentionOrgAndTeam[1]), LinkTypeApp) + link := "/:root/" + util.URLJoin("org", ctx.RenderOptions.Metas["org"], "teams", mentionOrgAndTeam[1]) replaceContent(node, loc.Start, loc.End, createLink(ctx, link, mention, "" /*mention*/)) node = node.NextSibling.NextSibling start = 0 @@ -45,7 +45,7 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) { mentionedUsername := mention[1:] if DefaultRenderHelperFuncs != nil && DefaultRenderHelperFuncs.IsUsernameMentionable(ctx, mentionedUsername) { - link := ctx.RenderHelper.ResolveLink(mentionedUsername, LinkTypeApp) + link := "/:root/" + mentionedUsername replaceContent(node, loc.Start, loc.End, createLink(ctx, link, mention, "" /*mention*/)) node = node.NextSibling.NextSibling start = 0 diff --git a/modules/markup/html_node.go b/modules/markup/html_node.go index 6e8ca67900..68858b024a 100644 --- a/modules/markup/html_node.go +++ b/modules/markup/html_node.go @@ -4,42 +4,79 @@ package markup import ( + "strings" + "golang.org/x/net/html" ) +func isAnchorIDUserContent(s string) bool { + // blackfridayExtRegex is for blackfriday extensions create IDs like fn:user-content-footnote + // old logic: blackfridayExtRegex = regexp.MustCompile(`[^:]*:user-content-`) + return strings.HasPrefix(s, "user-content-") || strings.Contains(s, ":user-content-") +} + +func processNodeAttrID(node *html.Node) { + // Add user-content- to IDs and "#" links if they don't already have them, + // and convert the link href to a relative link to the host root + for idx, attr := range node.Attr { + if attr.Key == "id" { + if !isAnchorIDUserContent(attr.Val) { + node.Attr[idx].Val = "user-content-" + attr.Val + } + } + } +} + +func processNodeA(ctx *RenderContext, node *html.Node) { + for idx, attr := range node.Attr { + if attr.Key == "href" { + if anchorID, ok := strings.CutPrefix(attr.Val, "#"); ok { + if !isAnchorIDUserContent(attr.Val) { + node.Attr[idx].Val = "#user-content-" + anchorID + } + } else { + node.Attr[idx].Val = ctx.RenderHelper.ResolveLink(attr.Val, LinkTypeDefault) + } + } + } +} + func visitNodeImg(ctx *RenderContext, img *html.Node) (next *html.Node) { next = img.NextSibling - for i, attr := range img.Attr { - if attr.Key != "src" { + for i, imgAttr := range img.Attr { + if imgAttr.Key != "src" { continue } - if IsNonEmptyRelativePath(attr.Val) { - attr.Val = ctx.RenderHelper.ResolveLink(attr.Val, LinkTypeMedia) + imgSrcOrigin := imgAttr.Val + isLinkable := imgSrcOrigin != "" && !strings.HasPrefix(imgSrcOrigin, "data:") - // By default, the "" tag should also be clickable, - // because frontend use `` to paste the re-scaled image into the markdown, - // so it must match the default markdown image behavior. - hasParentAnchor := false - for p := img.Parent; p != nil; p = p.Parent { - if hasParentAnchor = p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor { - break - } - } - if !hasParentAnchor { - imgA := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{ - {Key: "href", Val: attr.Val}, - {Key: "target", Val: "_blank"}, - }} - parent := img.Parent - imgNext := img.NextSibling - parent.RemoveChild(img) - parent.InsertBefore(imgA, imgNext) - imgA.AppendChild(img) + // By default, the "" tag should also be clickable, + // because frontend use `` to paste the re-scaled image into the markdown, + // so it must match the default markdown image behavior. + cnt := 0 + for p := img.Parent; isLinkable && p != nil && cnt < 2; p = p.Parent { + if hasParentAnchor := p.Type == html.ElementNode && p.Data == "a"; hasParentAnchor { + isLinkable = false + break } + cnt++ } - attr.Val = camoHandleLink(attr.Val) - img.Attr[i] = attr + if isLinkable { + wrapper := &html.Node{Type: html.ElementNode, Data: "a", Attr: []html.Attribute{ + {Key: "href", Val: ctx.RenderHelper.ResolveLink(imgSrcOrigin, LinkTypeDefault)}, + {Key: "target", Val: "_blank"}, + }} + parent := img.Parent + imgNext := img.NextSibling + parent.RemoveChild(img) + parent.InsertBefore(wrapper, imgNext) + wrapper.AppendChild(img) + } + + imgAttr.Val = ctx.RenderHelper.ResolveLink(imgSrcOrigin, LinkTypeMedia) + imgAttr.Val = camoHandleLink(imgAttr.Val) + img.Attr[i] = imgAttr } return next } diff --git a/modules/markup/html_test.go b/modules/markup/html_test.go index f0f062fa64..aab9fddd91 100644 --- a/modules/markup/html_test.go +++ b/modules/markup/html_test.go @@ -35,6 +35,7 @@ func TestRender_Commits(t *testing.T) { sha := "65f1bf27bc3bf70f64657658635e66094edbcb4d" repo := markup.TestAppURL + testRepoOwnerName + "/" + testRepoName + "/" commit := util.URLJoin(repo, "commit", sha) + commitPath := "/user13/repo11/commit/" + sha tree := util.URLJoin(repo, "tree", sha, "src") file := util.URLJoin(repo, "commit", sha, "example.txt") @@ -44,9 +45,9 @@ func TestRender_Commits(t *testing.T) { commitCompare := util.URLJoin(repo, "compare", sha+"..."+sha) commitCompareWithHash := commitCompare + "#L2" - test(sha, `65f1bf27bc`) - test(sha[:7], `65f1bf2`) - test(sha[:39], `65f1bf27bc`) + test(sha, `65f1bf27bc`) + test(sha[:7], `65f1bf2`) + test(sha[:39], `65f1bf27bc`) test(commit, `65f1bf27bc`) test(tree, `65f1bf27bc/src`) @@ -57,13 +58,13 @@ func TestRender_Commits(t *testing.T) { test(commitCompare, `65f1bf27bc...65f1bf27bc`) test(commitCompareWithHash, `65f1bf27bc...65f1bf27bc (L2)`) - test("commit "+sha, `commit 65f1bf27bc`) + test("commit "+sha, `commit 65f1bf27bc`) test("/home/gitea/"+sha, "/home/gitea/"+sha+"") test("deadbeef", `deadbeef`) test("d27ace93", `d27ace93`) test(sha[:14]+".x", ``+sha[:14]+`.x`) - expected14 := `` + sha[:10] + `` + expected14 := `` + sha[:10] + `` test(sha[:14]+".", ``+expected14+`.`) test(sha[:14]+",", ``+expected14+`,`) test("["+sha[:14]+"]", `[`+expected14+`]`) @@ -80,10 +81,10 @@ func TestRender_CrossReferences(t *testing.T) { test( "test-owner/test-repo#12345", - `test-owner/test-repo#12345`) + `test-owner/test-repo#12345`) test( "go-gitea/gitea#12345", - `go-gitea/gitea#12345`) + `go-gitea/gitea#12345`) test( "/home/gitea/go-gitea/gitea#12345", `/home/gitea/go-gitea/gitea#12345`) @@ -468,7 +469,7 @@ func Test_ParseClusterFuzz(t *testing.T) { assert.NotContains(t, res.String(), "go-gitea/gitea#12345`) + `go-gitea/gitea#12345`) - // Test that other post processing still works. + // Test that other post-processing still works. test( ":gitea:", ``) @@ -498,6 +499,12 @@ func TestPostProcess_RenderDocument(t *testing.T) { `Some text with 😄 in the middle`) test("http://localhost:3000/person/repo/issues/4#issuecomment-1234", `person/repo#4 (comment)`) + + // special tags, GitHub's behavior, and for unclosed tags, output as text content as much as possible + test("", `<script>a</script>`) + test("", `<style>a</STYLE>`) } func TestIssue16020(t *testing.T) { @@ -543,7 +550,7 @@ func TestIssue18471(t *testing.T) { err := markup.PostProcessDefault(markup.NewTestRenderContext(localMetas), strings.NewReader(data), &res) assert.NoError(t, err) - assert.Equal(t, `783b039...da951ce`, res.String()) + assert.Equal(t, `783b039...da951ce`, res.String()) } func TestIsFullURL(t *testing.T) { diff --git a/modules/markup/internal/internal_test.go b/modules/markup/internal/internal_test.go index 98ff3bc079..590bcbb67f 100644 --- a/modules/markup/internal/internal_test.go +++ b/modules/markup/internal/internal_test.go @@ -35,7 +35,7 @@ func TestRenderInternal(t *testing.T) { assert.EqualValues(t, c.protected, protected) _, _ = io.WriteString(in, string(protected)) _ = in.Close() - assert.EqualValues(t, c.recovered, out.String()) + assert.Equal(t, c.recovered, out.String()) } var r1, r2 RenderInternal @@ -44,11 +44,11 @@ func TestRenderInternal(t *testing.T) { _ = r1.init("sec", nil) protected = r1.ProtectSafeAttrs(``) assert.EqualValues(t, ``, protected) - assert.EqualValues(t, "data-attr-class", r1.SafeAttr("class")) - assert.EqualValues(t, "sec:val", r1.SafeValue("val")) + assert.Equal(t, "data-attr-class", r1.SafeAttr("class")) + assert.Equal(t, "sec:val", r1.SafeValue("val")) recovered, ok := r1.RecoverProtectedValue("sec:val") assert.True(t, ok) - assert.EqualValues(t, "val", recovered) + assert.Equal(t, "val", recovered) recovered, ok = r1.RecoverProtectedValue("other:val") assert.False(t, ok) assert.Empty(t, recovered) @@ -57,5 +57,5 @@ func TestRenderInternal(t *testing.T) { in2 := r2.init("sec-other", out2) _, _ = io.WriteString(in2, string(protected)) _ = in2.Close() - assert.EqualValues(t, ``, out2.String(), "different secureID should not recover the value") + assert.Equal(t, ``, out2.String(), "different secureID should not recover the value") } diff --git a/modules/markup/markdown/ast.go b/modules/markup/markdown/ast.go index ca165b1ba0..f29f883734 100644 --- a/modules/markup/markdown/ast.go +++ b/modules/markup/markdown/ast.go @@ -4,6 +4,7 @@ package markdown import ( + "html/template" "strconv" "github.com/yuin/goldmark/ast" @@ -29,9 +30,7 @@ func (n *Details) Kind() ast.NodeKind { // NewDetails returns a new Paragraph node. func NewDetails() *Details { - return &Details{ - BaseBlock: ast.BaseBlock{}, - } + return &Details{} } // Summary is a block that contains the summary of details block @@ -54,9 +53,7 @@ func (n *Summary) Kind() ast.NodeKind { // NewSummary returns a new Summary node. func NewSummary() *Summary { - return &Summary{ - BaseBlock: ast.BaseBlock{}, - } + return &Summary{} } // TaskCheckBoxListItem is a block that represents a list item of a markdown block with a checkbox @@ -95,29 +92,6 @@ type Icon struct { Name []byte } -// Dump implements Node.Dump . -func (n *Icon) Dump(source []byte, level int) { - m := map[string]string{} - m["Name"] = string(n.Name) - ast.DumpHelper(n, source, level, m, nil) -} - -// KindIcon is the NodeKind for Icon -var KindIcon = ast.NewNodeKind("Icon") - -// Kind implements Node.Kind. -func (n *Icon) Kind() ast.NodeKind { - return KindIcon -} - -// NewIcon returns a new Paragraph node. -func NewIcon(name string) *Icon { - return &Icon{ - BaseInline: ast.BaseInline{}, - Name: []byte(name), - } -} - // ColorPreview is an inline for a color preview type ColorPreview struct { ast.BaseInline @@ -175,3 +149,24 @@ func NewAttention(attentionType string) *Attention { AttentionType: attentionType, } } + +var KindRawHTML = ast.NewNodeKind("RawHTML") + +type RawHTML struct { + ast.BaseBlock + rawHTML template.HTML +} + +func (n *RawHTML) Dump(source []byte, level int) { + m := map[string]string{} + m["RawHTML"] = string(n.rawHTML) + ast.DumpHelper(n, source, level, m, nil) +} + +func (n *RawHTML) Kind() ast.NodeKind { + return KindRawHTML +} + +func NewRawHTML(rawHTML template.HTML) *RawHTML { + return &RawHTML{rawHTML: rawHTML} +} diff --git a/modules/markup/markdown/convertyaml.go b/modules/markup/markdown/convertyaml.go index 1675b68be2..04664a9c1d 100644 --- a/modules/markup/markdown/convertyaml.go +++ b/modules/markup/markdown/convertyaml.go @@ -4,23 +4,22 @@ package markdown import ( + "strings" + + "code.gitea.io/gitea/modules/htmlutil" + "code.gitea.io/gitea/modules/svg" + "github.com/yuin/goldmark/ast" east "github.com/yuin/goldmark/extension/ast" "gopkg.in/yaml.v3" ) func nodeToTable(meta *yaml.Node) ast.Node { - for { - if meta == nil { - return nil - } - switch meta.Kind { - case yaml.DocumentNode: - meta = meta.Content[0] - continue - default: - } - break + for meta != nil && meta.Kind == yaml.DocumentNode { + meta = meta.Content[0] + } + if meta == nil { + return nil } switch meta.Kind { case yaml.MappingNode: @@ -72,12 +71,28 @@ func sequenceNodeToTable(meta *yaml.Node) ast.Node { return table } -func nodeToDetails(meta *yaml.Node, icon string) ast.Node { +func nodeToDetails(g *ASTTransformer, meta *yaml.Node) ast.Node { + for meta != nil && meta.Kind == yaml.DocumentNode { + meta = meta.Content[0] + } + if meta == nil { + return nil + } + if meta.Kind != yaml.MappingNode { + return nil + } + var keys []string + for i := 0; i < len(meta.Content); i += 2 { + if meta.Content[i].Kind == yaml.ScalarNode { + keys = append(keys, meta.Content[i].Value) + } + } details := NewDetails() + details.SetAttributeString(g.renderInternal.SafeAttr("class"), g.renderInternal.SafeValue("frontmatter-content")) summary := NewSummary() - summary.AppendChild(summary, NewIcon(icon)) + summaryInnerHTML := htmlutil.HTMLFormat("%s %s", svg.RenderHTML("octicon-table", 12), strings.Join(keys, ", ")) + summary.AppendChild(summary, NewRawHTML(summaryInnerHTML)) details.AppendChild(details, summary) details.AppendChild(details, nodeToTable(meta)) - return details } diff --git a/modules/markup/markdown/goldmark.go b/modules/markup/markdown/goldmark.go index 3021f4bdde..b28fa9824e 100644 --- a/modules/markup/markdown/goldmark.go +++ b/modules/markup/markdown/goldmark.go @@ -5,14 +5,10 @@ package markdown import ( "fmt" - "regexp" - "strings" - "sync" "code.gitea.io/gitea/modules/container" "code.gitea.io/gitea/modules/markup" "code.gitea.io/gitea/modules/markup/internal" - "code.gitea.io/gitea/modules/setting" "github.com/yuin/goldmark/ast" east "github.com/yuin/goldmark/extension/ast" @@ -51,7 +47,7 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa tocList := make([]Header, 0, 20) if rc.yamlNode != nil { - metaNode := rc.toMetaNode() + metaNode := rc.toMetaNode(g) if metaNode != nil { node.InsertBefore(node, firstChild, metaNode) } @@ -68,24 +64,12 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa g.transformHeading(ctx, v, reader, &tocList) case *ast.Paragraph: g.applyElementDir(v) - case *ast.Image: - g.transformImage(ctx, v) - case *ast.Link: - g.transformLink(ctx, v) case *ast.List: g.transformList(ctx, v, rc) case *ast.Text: if v.SoftLineBreak() && !v.HardLineBreak() { - // TODO: this was a quite unclear part, old code: `if metas["mode"] != "document" { use comment link break setting }` - // many places render non-comment contents with no mode=document, then these contents also use comment's hard line break setting - // especially in many tests. - markdownLineBreakStyle := ctx.RenderOptions.Metas["markdownLineBreakStyle"] - switch markdownLineBreakStyle { - case "comment": - v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInComments) - case "document": - v.SetHardLineBreak(setting.Markdown.EnableHardLineBreakInDocuments) - } + newLineHardBreak := ctx.RenderOptions.Metas["markdownNewLineHardBreak"] == "true" + v.SetHardLineBreak(newLineHardBreak) } case *ast.CodeSpan: g.transformCodeSpan(ctx, v, reader) @@ -112,11 +96,6 @@ func (g *ASTTransformer) Transform(node *ast.Document, reader text.Reader, pc pa } } -// it is copied from old code, which is quite doubtful whether it is correct -var reValidIconName = sync.OnceValue(func() *regexp.Regexp { - return regexp.MustCompile(`^[-\w]+$`) // old: regexp.MustCompile("^[a-z ]+$") -}) - // NewHTMLRenderer creates a HTMLRenderer to render in the gitea form. func NewHTMLRenderer(renderInternal *internal.RenderInternal, opts ...html.Option) renderer.NodeRenderer { r := &HTMLRenderer{ @@ -141,11 +120,11 @@ func (r *HTMLRenderer) RegisterFuncs(reg renderer.NodeRendererFuncRegisterer) { reg.Register(ast.KindDocument, r.renderDocument) reg.Register(KindDetails, r.renderDetails) reg.Register(KindSummary, r.renderSummary) - reg.Register(KindIcon, r.renderIcon) reg.Register(ast.KindCodeSpan, r.renderCodeSpan) reg.Register(KindAttention, r.renderAttention) reg.Register(KindTaskCheckBoxListItem, r.renderTaskCheckBoxListItem) reg.Register(east.KindTaskCheckBox, r.renderTaskCheckBox) + reg.Register(KindRawHTML, r.renderRawHTML) } func (r *HTMLRenderer) renderDocument(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { @@ -207,30 +186,14 @@ func (r *HTMLRenderer) renderSummary(w util.BufWriter, source []byte, node ast.N return ast.WalkContinue, nil } -func (r *HTMLRenderer) renderIcon(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { +func (r *HTMLRenderer) renderRawHTML(w util.BufWriter, source []byte, node ast.Node, entering bool) (ast.WalkStatus, error) { if !entering { return ast.WalkContinue, nil } - - n := node.(*Icon) - - name := strings.TrimSpace(strings.ToLower(string(n.Name))) - - if len(name) == 0 { - // skip this - return ast.WalkContinue, nil - } - - if !reValidIconName().MatchString(name) { - // skip this - return ast.WalkContinue, nil - } - - // FIXME: the "icon xxx" is from Fomantic UI, it's really questionable whether it still works correctly - err := r.renderInternal.FormatWithSafeAttrs(w, ``, name) + n := node.(*RawHTML) + _, err := w.WriteString(string(r.renderInternal.ProtectSafeAttrs(n.rawHTML))) if err != nil { return ast.WalkStop, err } - return ast.WalkContinue, nil } diff --git a/modules/markup/markdown/markdown.go b/modules/markup/markdown/markdown.go index ace31eb540..0d7180c6b1 100644 --- a/modules/markup/markdown/markdown.go +++ b/modules/markup/markdown/markdown.go @@ -5,7 +5,7 @@ package markdown import ( - "fmt" + "errors" "html/template" "io" "strings" @@ -48,7 +48,7 @@ func (l *limitWriter) Write(data []byte) (int, error) { if err != nil { return n, err } - return n, fmt.Errorf("rendered content too large - truncating render") + return n, errors.New("rendered content too large - truncating render") } n, err := l.w.Write(data) l.sum += int64(n) @@ -126,11 +126,11 @@ func SpecializedMarkdown(ctx *markup.RenderContext) *GlodmarkRender { highlighting.WithWrapperRenderer(r.highlightingRenderer), ), math.NewExtension(&ctx.RenderInternal, math.Options{ - Enabled: setting.Markdown.EnableMath, - ParseDollarInline: true, - ParseDollarBlock: true, - ParseSquareBlock: true, // TODO: this is a bad syntax "\[ ... \]", it conflicts with normal markdown escaping, it should be deprecated in the future (by some config options) - // ParseBracketInline: true, // TODO: this is also a bad syntax "\( ... \)", it also conflicts, it should be deprecated in the future + Enabled: setting.Markdown.EnableMath, + ParseInlineDollar: setting.Markdown.MathCodeBlockOptions.ParseInlineDollar, + ParseInlineParentheses: setting.Markdown.MathCodeBlockOptions.ParseInlineParentheses, // this is a bad syntax "\( ... \)", it conflicts with normal markdown escaping + ParseBlockDollar: setting.Markdown.MathCodeBlockOptions.ParseBlockDollar, + ParseBlockSquareBrackets: setting.Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets, // this is a bad syntax "\[ ... \]", it conflicts with normal markdown escaping }), meta.Meta, ), @@ -184,11 +184,7 @@ func render(ctx *markup.RenderContext, input io.Reader, output io.Writer) error // Preserve original length. bufWithMetadataLength := len(buf) - rc := &RenderConfig{ - Meta: markup.RenderMetaAsDetails, - Icon: "table", - Lang: "", - } + rc := &RenderConfig{Meta: markup.RenderMetaAsDetails} buf, _ = ExtractMetadataBytes(buf, rc) metaLength := bufWithMetadataLength - len(buf) diff --git a/modules/markup/markdown/markdown_math_test.go b/modules/markup/markdown/markdown_math_test.go index 813f050965..a75f18d36a 100644 --- a/modules/markup/markdown/markdown_math_test.go +++ b/modules/markup/markdown/markdown_math_test.go @@ -8,6 +8,8 @@ import ( "testing" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" ) @@ -15,6 +17,7 @@ import ( const nl = "\n" func TestMathRender(t *testing.T) { + setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true} testcases := []struct { testcase string expected string @@ -69,7 +72,7 @@ func TestMathRender(t *testing.T) { }, { "$$a$$", - `a` + nl, + `a` + nl, }, { "$$a$$ test", @@ -111,6 +114,7 @@ func TestMathRender(t *testing.T) { } func TestMathRenderBlockIndent(t *testing.T) { + setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{ParseBlockDollar: true, ParseBlockSquareBrackets: true} testcases := []struct { name string testcase string @@ -243,3 +247,64 @@ x }) } } + +func TestMathRenderOptions(t *testing.T) { + setting.Markdown.MathCodeBlockOptions = setting.MarkdownMathCodeBlockOptions{} + defer test.MockVariableValue(&setting.Markdown.MathCodeBlockOptions) + test := func(t *testing.T, expected, input string) { + res, err := RenderString(markup.NewTestRenderContext(), input) + assert.NoError(t, err) + assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(string(res)), "input: %s", input) + } + + // default (non-conflict) inline syntax + test(t, `a`, "$`a`$") + + // ParseInlineDollar + test(t, `$a$`, `$a$`) + setting.Markdown.MathCodeBlockOptions.ParseInlineDollar = true + test(t, `a`, `$a$`) + + // ParseInlineParentheses + test(t, `(a)`, `\(a\)`) + setting.Markdown.MathCodeBlockOptions.ParseInlineParentheses = true + test(t, `a`, `\(a\)`) + + // ParseBlockDollar + test(t, `$$ +a +$$ +`, ` +$$ +a +$$ +`) + setting.Markdown.MathCodeBlockOptions.ParseBlockDollar = true + test(t, ` +a + +`, ` +$$ +a +$$ +`) + + // ParseBlockSquareBrackets + test(t, `[ +a +] +`, ` +\[ +a +\] +`) + setting.Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true + test(t, ` +a + +`, ` +\[ +a +\] +`) +} diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go index 7a09be8665..2310895fc3 100644 --- a/modules/markup/markdown/markdown_test.go +++ b/modules/markup/markdown/markdown_test.go @@ -308,12 +308,12 @@ func TestRenderSiblingImages_Issue12925(t *testing.T) { testcase := `  ` - expected := ` - + expected := ` + ` - res, err := markdown.RenderRawString(markup.NewTestRenderContext(), testcase) + res, err := markdown.RenderString(markup.NewTestRenderContext(), testcase) assert.NoError(t, err) - assert.Equal(t, expected, res) + assert.Equal(t, expected, string(res)) } func TestRenderEmojiInLinks_Issue12331(t *testing.T) { @@ -383,18 +383,74 @@ func TestColorPreview(t *testing.T) { } } -func TestTaskList(t *testing.T) { +func TestMarkdownFrontmatter(t *testing.T) { testcases := []struct { - testcase string + name string + input string expected string }{ + { + "MapInFrontmatter", + `--- +key1: val1 +key2: val2 +--- +test +`, + `octicon-table(12/) key1, key2 + + +key1 +key2 + + + + +val1 +val2 + + + +test +`, + }, + + { + "ListInFrontmatter", + `--- +- item1 +- item2 +--- +test +`, + `- item1 +- item2 + +test +`, + }, + + { + "StringInFrontmatter", + `--- +anything +--- +test +`, + `anything + +test +`, + }, + { // data-source-position should take into account YAML frontmatter. + "ListAfterFrontmatter", `--- foo: bar --- - [ ] task 1`, - ` + `octicon-table(12/) foo foo @@ -414,9 +470,9 @@ foo: bar } for _, test := range testcases { - res, err := markdown.RenderString(markup.NewTestRenderContext(), test.testcase) - assert.NoError(t, err, "Unexpected error in testcase: %q", test.testcase) - assert.Equal(t, template.HTML(test.expected), res, "Unexpected result in testcase %q", test.testcase) + res, err := markdown.RenderString(markup.NewTestRenderContext(), test.input) + assert.NoError(t, err, "Unexpected error in testcase: %q", test.name) + assert.Equal(t, test.expected, string(res), "Unexpected result in testcase %q", test.name) } } @@ -473,3 +529,16 @@ space assert.NoError(t, err) assert.Equal(t, expected, string(result)) } + +func TestMarkdownLink(t *testing.T) { + defer test.MockVariableValue(&markup.RenderBehaviorForTesting.DisableAdditionalAttributes, true)() + input := `link1 +link2 +link3` + result, err := markdown.RenderString(markup.NewTestRenderContext("/base", localMetas), input) + assert.NoError(t, err) + assert.Equal(t, `link1 +link2 +link3 +`, string(result)) +} diff --git a/modules/markup/markdown/math/inline_parser.go b/modules/markup/markdown/math/inline_parser.go index d24fd50955..a711d1e1cd 100644 --- a/modules/markup/markdown/math/inline_parser.go +++ b/modules/markup/markdown/math/inline_parser.go @@ -15,26 +15,26 @@ type inlineParser struct { trigger []byte endBytesSingleDollar []byte endBytesDoubleDollar []byte - endBytesBracket []byte + endBytesParentheses []byte + enableInlineDollar bool } -var defaultInlineDollarParser = &inlineParser{ - trigger: []byte{'$'}, - endBytesSingleDollar: []byte{'$'}, - endBytesDoubleDollar: []byte{'$', '$'}, +func NewInlineDollarParser(enableInlineDollar bool) parser.InlineParser { + return &inlineParser{ + trigger: []byte{'$'}, + endBytesSingleDollar: []byte{'$'}, + endBytesDoubleDollar: []byte{'$', '$'}, + enableInlineDollar: enableInlineDollar, + } } -func NewInlineDollarParser() parser.InlineParser { - return defaultInlineDollarParser +var defaultInlineParenthesesParser = &inlineParser{ + trigger: []byte{'\\', '('}, + endBytesParentheses: []byte{'\\', ')'}, } -var defaultInlineBracketParser = &inlineParser{ - trigger: []byte{'\\', '('}, - endBytesBracket: []byte{'\\', ')'}, -} - -func NewInlineBracketParser() parser.InlineParser { - return defaultInlineBracketParser +func NewInlineParenthesesParser() parser.InlineParser { + return defaultInlineParenthesesParser } // Trigger triggers this parser on $ or \ @@ -46,7 +46,7 @@ func isPunctuation(b byte) bool { return b == '.' || b == '!' || b == '?' || b == ',' || b == ';' || b == ':' } -func isBracket(b byte) bool { +func isParenthesesClose(b byte) bool { return b == ')' } @@ -86,7 +86,11 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser. } } else { startMarkLen = 2 - stopMark = parser.endBytesBracket + stopMark = parser.endBytesParentheses + } + + if line[0] == '$' && !parser.enableInlineDollar && (len(line) == 1 || line[1] != '`') { + return nil } if checkSurrounding { @@ -110,7 +114,7 @@ func (parser *inlineParser) Parse(parent ast.Node, block text.Reader, pc parser. succeedingCharacter = line[i+len(stopMark)] } // check valid ending character - isValidEndingChar := isPunctuation(succeedingCharacter) || isBracket(succeedingCharacter) || + isValidEndingChar := isPunctuation(succeedingCharacter) || isParenthesesClose(succeedingCharacter) || succeedingCharacter == ' ' || succeedingCharacter == '\n' || succeedingCharacter == 0 if checkSurrounding && !isValidEndingChar { break diff --git a/modules/markup/markdown/math/math.go b/modules/markup/markdown/math/math.go index a6ff593d62..4b74db2d76 100644 --- a/modules/markup/markdown/math/math.go +++ b/modules/markup/markdown/math/math.go @@ -14,10 +14,11 @@ import ( ) type Options struct { - Enabled bool - ParseDollarInline bool - ParseDollarBlock bool - ParseSquareBlock bool + Enabled bool + ParseInlineDollar bool // inline $$ xxx $$ text + ParseInlineParentheses bool // inline \( xxx \) text + ParseBlockDollar bool // block $$ multiple-line $$ text + ParseBlockSquareBrackets bool // block \[ multiple-line \] text } // Extension is a math extension @@ -42,16 +43,16 @@ func (e *Extension) Extend(m goldmark.Markdown) { return } - inlines := []util.PrioritizedValue{util.Prioritized(NewInlineBracketParser(), 501)} - if e.options.ParseDollarInline { - inlines = append(inlines, util.Prioritized(NewInlineDollarParser(), 502)) + var inlines []util.PrioritizedValue + if e.options.ParseInlineParentheses { + inlines = append(inlines, util.Prioritized(NewInlineParenthesesParser(), 501)) } + inlines = append(inlines, util.Prioritized(NewInlineDollarParser(e.options.ParseInlineDollar), 502)) + m.Parser().AddOptions(parser.WithInlineParsers(inlines...)) - m.Parser().AddOptions(parser.WithBlockParsers( - util.Prioritized(NewBlockParser(e.options.ParseDollarBlock, e.options.ParseSquareBlock), 701), + util.Prioritized(NewBlockParser(e.options.ParseBlockDollar, e.options.ParseBlockSquareBrackets), 701), )) - m.Renderer().AddOptions(renderer.WithNodeRenderers( util.Prioritized(NewBlockRenderer(e.renderInternal), 501), util.Prioritized(NewInlineRenderer(e.renderInternal), 502), diff --git a/modules/markup/markdown/meta_test.go b/modules/markup/markdown/meta_test.go index 278c33f1d2..3f74adeaef 100644 --- a/modules/markup/markdown/meta_test.go +++ b/modules/markup/markdown/meta_test.go @@ -51,7 +51,7 @@ func TestExtractMetadata(t *testing.T) { var meta IssueTemplate body, err := ExtractMetadata(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest), &meta) assert.NoError(t, err) - assert.Equal(t, "", body) + assert.Empty(t, body) assert.Equal(t, metaTest, meta) assert.True(t, meta.Valid()) }) @@ -83,7 +83,7 @@ func TestExtractMetadataBytes(t *testing.T) { var meta IssueTemplate body, err := ExtractMetadataBytes([]byte(fmt.Sprintf("%s\n%s\n%s", sepTest, frontTest, sepTest)), &meta) assert.NoError(t, err) - assert.Equal(t, "", string(body)) + assert.Empty(t, string(body)) assert.Equal(t, metaTest, meta) assert.True(t, meta.Valid()) }) diff --git a/modules/markup/markdown/renderconfig.go b/modules/markup/markdown/renderconfig.go index f4c48d1b3d..d8b1b10ce6 100644 --- a/modules/markup/markdown/renderconfig.go +++ b/modules/markup/markdown/renderconfig.go @@ -16,7 +16,6 @@ import ( // RenderConfig represents rendering configuration for this file type RenderConfig struct { Meta markup.RenderMetaMode - Icon string TOC string // "false": hide, "side"/empty: in sidebar, "main"/"true": in main view Lang string yamlNode *yaml.Node @@ -74,7 +73,7 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { type yamlRenderConfig struct { Meta *string `yaml:"meta"` - Icon *string `yaml:"details_icon"` + Icon *string `yaml:"details_icon"` // deprecated, because there is no font icon, so no custom icon TOC *string `yaml:"include_toc"` Lang *string `yaml:"lang"` } @@ -96,10 +95,6 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { rc.Meta = renderMetaModeFromString(*cfg.Gitea.Meta) } - if cfg.Gitea.Icon != nil { - rc.Icon = strings.TrimSpace(strings.ToLower(*cfg.Gitea.Icon)) - } - if cfg.Gitea.Lang != nil && *cfg.Gitea.Lang != "" { rc.Lang = *cfg.Gitea.Lang } @@ -111,7 +106,7 @@ func (rc *RenderConfig) UnmarshalYAML(value *yaml.Node) error { return nil } -func (rc *RenderConfig) toMetaNode() ast.Node { +func (rc *RenderConfig) toMetaNode(g *ASTTransformer) ast.Node { if rc.yamlNode == nil { return nil } @@ -119,7 +114,7 @@ func (rc *RenderConfig) toMetaNode() ast.Node { case markup.RenderMetaAsTable: return nodeToTable(rc.yamlNode) case markup.RenderMetaAsDetails: - return nodeToDetails(rc.yamlNode, rc.Icon) + return nodeToDetails(g, rc.yamlNode) default: return nil } diff --git a/modules/markup/markdown/renderconfig_test.go b/modules/markup/markdown/renderconfig_test.go index 13346570fa..53c52177a7 100644 --- a/modules/markup/markdown/renderconfig_test.go +++ b/modules/markup/markdown/renderconfig_test.go @@ -21,42 +21,36 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { { "empty", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "", }, "", }, { "lang", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "test", }, "lang: test", }, { "metatable", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "", }, "gitea: table", }, { "metanone", &RenderConfig{ Meta: "none", - Icon: "table", Lang: "", }, "gitea: none", }, { "metadetails", &RenderConfig{ Meta: "details", - Icon: "table", Lang: "", }, "gitea: details", }, { "metawrong", &RenderConfig{ Meta: "details", - Icon: "table", Lang: "", }, "gitea: wrong", }, @@ -64,7 +58,6 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { "toc", &RenderConfig{ TOC: "true", Meta: "table", - Icon: "table", Lang: "", }, "include_toc: true", }, @@ -72,14 +65,12 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { "tocfalse", &RenderConfig{ TOC: "false", Meta: "table", - Icon: "table", Lang: "", }, "include_toc: false", }, { "toclang", &RenderConfig{ Meta: "table", - Icon: "table", TOC: "true", Lang: "testlang", }, ` @@ -90,7 +81,6 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { { "complexlang", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "testlang", }, ` gitea: @@ -100,7 +90,6 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { { "complexlang2", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "testlang", }, ` lang: notright @@ -111,7 +100,6 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { { "complexlang", &RenderConfig{ Meta: "table", - Icon: "table", Lang: "testlang", }, ` gitea: @@ -123,7 +111,6 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { Lang: "two", Meta: "table", TOC: "true", - Icon: "smiley", }, ` lang: one include_toc: true @@ -139,14 +126,12 @@ func TestRenderConfig_UnmarshalYAML(t *testing.T) { t.Run(tt.name, func(t *testing.T) { got := &RenderConfig{ Meta: "table", - Icon: "table", Lang: "", } err := yaml.Unmarshal([]byte(strings.ReplaceAll(tt.args, "\t", " ")), got) require.NoError(t, err) assert.Equal(t, tt.expected.Meta, got.Meta) - assert.Equal(t, tt.expected.Icon, got.Icon) assert.Equal(t, tt.expected.Lang, got.Lang) assert.Equal(t, tt.expected.TOC, got.TOC) }) diff --git a/modules/markup/markdown/toc.go b/modules/markup/markdown/toc.go index ea1af83a3e..a11b9d0390 100644 --- a/modules/markup/markdown/toc.go +++ b/modules/markup/markdown/toc.go @@ -4,7 +4,6 @@ package markdown import ( - "fmt" "net/url" "code.gitea.io/gitea/modules/translation" @@ -50,7 +49,7 @@ func createTOCNode(toc []Header, lang string, detailsAttrs map[string]string) as } li := ast.NewListItem(currentLevel * 2) a := ast.NewLink() - a.Destination = []byte(fmt.Sprintf("#%s", url.QueryEscape(header.ID))) + a.Destination = []byte("#" + url.QueryEscape(header.ID)) a.AppendChild(a, ast.NewString([]byte(header.Text))) li.AppendChild(li, a) ul.AppendChild(ul, li) diff --git a/modules/markup/markdown/transform_image.go b/modules/markup/markdown/transform_image.go deleted file mode 100644 index 36512e59a8..0000000000 --- a/modules/markup/markdown/transform_image.go +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package markdown - -import ( - "code.gitea.io/gitea/modules/markup" - - "github.com/yuin/goldmark/ast" -) - -func (g *ASTTransformer) transformImage(ctx *markup.RenderContext, v *ast.Image) { - // Images need two things: - // - // 1. Their src needs to munged to be a real value - // 2. If they're not wrapped with a link they need a link wrapper - - // Check if the destination is a real link - if len(v.Destination) > 0 && !markup.IsFullURLBytes(v.Destination) { - v.Destination = []byte(ctx.RenderHelper.ResolveLink(string(v.Destination), markup.LinkTypeMedia)) - } - - parent := v.Parent() - // Create a link around image only if parent is not already a link - if _, ok := parent.(*ast.Link); !ok && parent != nil { - next := v.NextSibling() - - // Create a link wrapper - wrap := ast.NewLink() - wrap.Destination = v.Destination - wrap.Title = v.Title - wrap.SetAttributeString("target", []byte("_blank")) - - // Duplicate the current image node - image := ast.NewImage(ast.NewLink()) - image.Destination = v.Destination - image.Title = v.Title - for _, attr := range v.Attributes() { - image.SetAttribute(attr.Name, attr.Value) - } - for child := v.FirstChild(); child != nil; { - next := child.NextSibling() - image.AppendChild(image, child) - child = next - } - - // Append our duplicate image to the wrapper link - wrap.AppendChild(wrap, image) - - // Wire in the next sibling - wrap.SetNextSibling(next) - - // Replace the current node with the wrapper link - parent.ReplaceChild(parent, v, wrap) - - // But most importantly ensure the next sibling is still on the old image too - v.SetNextSibling(next) - } -} diff --git a/modules/markup/markdown/transform_link.go b/modules/markup/markdown/transform_link.go deleted file mode 100644 index 51c2c915d8..0000000000 --- a/modules/markup/markdown/transform_link.go +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2024 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package markdown - -import ( - "code.gitea.io/gitea/modules/markup" - - "github.com/yuin/goldmark/ast" -) - -func resolveLink(ctx *markup.RenderContext, link, userContentAnchorPrefix string) (result string, resolved bool) { - isAnchorFragment := link != "" && link[0] == '#' - if !isAnchorFragment && !markup.IsFullURLString(link) { - link, resolved = ctx.RenderHelper.ResolveLink(link, markup.LinkTypeDefault), true - } - if isAnchorFragment && userContentAnchorPrefix != "" { - link, resolved = userContentAnchorPrefix+link[1:], true - } - return link, resolved -} - -func (g *ASTTransformer) transformLink(ctx *markup.RenderContext, v *ast.Link) { - if link, resolved := resolveLink(ctx, string(v.Destination), "#user-content-"); resolved { - v.Destination = []byte(link) - } -} diff --git a/modules/markup/mdstripper/mdstripper_test.go b/modules/markup/mdstripper/mdstripper_test.go index ea34df0a3b..7fb49c1e01 100644 --- a/modules/markup/mdstripper/mdstripper_test.go +++ b/modules/markup/mdstripper/mdstripper_test.go @@ -79,7 +79,7 @@ A HIDDEN ` + "`" + `GHOST` + "`" + ` IN THIS LINE. lines = append(lines, line) } } - assert.EqualValues(t, test.expectedText, lines) - assert.EqualValues(t, test.expectedLinks, links) + assert.Equal(t, test.expectedText, lines) + assert.Equal(t, test.expectedLinks, links) } } diff --git a/modules/markup/orgmode/orgmode.go b/modules/markup/orgmode/orgmode.go index 70d02c1321..93c335d244 100644 --- a/modules/markup/orgmode/orgmode.go +++ b/modules/markup/orgmode/orgmode.go @@ -1,7 +1,7 @@ // Copyright 2017 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package markup +package orgmode import ( "fmt" @@ -125,27 +125,13 @@ type orgWriter struct { var _ org.Writer = (*orgWriter)(nil) -func (r *orgWriter) resolveLink(kind, link string) string { - link = strings.TrimPrefix(link, "file:") - if !strings.HasPrefix(link, "#") && // not a URL fragment - !markup.IsFullURLString(link) { - if kind == "regular" { - // orgmode reports the link kind as "regular" for "[[ImageLink.svg][The Image Desc]]" - // so we need to try to guess the link kind again here - kind = org.RegularLink{URL: link}.Kind() - } - if kind == "image" || kind == "video" { - link = r.rctx.RenderHelper.ResolveLink(link, markup.LinkTypeMedia) - } else { - link = r.rctx.RenderHelper.ResolveLink(link, markup.LinkTypeDefault) - } - } - return link +func (r *orgWriter) resolveLink(link string) string { + return strings.TrimPrefix(link, "file:") } // WriteRegularLink renders images, links or videos func (r *orgWriter) WriteRegularLink(l org.RegularLink) { - link := r.resolveLink(l.Kind(), l.URL) + link := r.resolveLink(l.URL) printHTML := func(html template.HTML, a ...any) { _, _ = fmt.Fprint(r, htmlutil.HTMLFormat(html, a...)) @@ -156,14 +142,14 @@ func (r *orgWriter) WriteRegularLink(l org.RegularLink) { if l.Description == nil { printHTML(``, link, link) } else { - imageSrc := r.resolveLink(l.Kind(), org.String(l.Description...)) + imageSrc := r.resolveLink(org.String(l.Description...)) printHTML(``, link, imageSrc, imageSrc) } case "video": if l.Description == nil { printHTML(`%s`, link, link) } else { - videoSrc := r.resolveLink(l.Kind(), org.String(l.Description...)) + videoSrc := r.resolveLink(org.String(l.Description...)) printHTML(`%s`, link, videoSrc, videoSrc) } default: diff --git a/modules/markup/orgmode/orgmode_test.go b/modules/markup/orgmode/orgmode_test.go index de39bafebe..df4bb38ad1 100644 --- a/modules/markup/orgmode/orgmode_test.go +++ b/modules/markup/orgmode/orgmode_test.go @@ -1,7 +1,7 @@ // Copyright 2017 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -package markup +package orgmode_test import ( "os" @@ -9,6 +9,7 @@ import ( "testing" "code.gitea.io/gitea/modules/markup" + "code.gitea.io/gitea/modules/markup/orgmode" "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" @@ -22,7 +23,7 @@ func TestMain(m *testing.M) { func TestRender_StandardLinks(t *testing.T) { test := func(input, expected string) { - buffer, err := RenderString(markup.NewTestRenderContext("/relative-path/media/branch/main/"), input) + buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } @@ -30,37 +31,37 @@ func TestRender_StandardLinks(t *testing.T) { test("[[https://google.com/]]", `https://google.com/`) test("[[ImageLink.svg][The Image Desc]]", - `The Image Desc`) + `The Image Desc`) } func TestRender_InternalLinks(t *testing.T) { test := func(input, expected string) { - buffer, err := RenderString(markup.NewTestRenderContext("/relative-path/src/branch/main"), input) + buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } test("[[file:test.org][Test]]", - `Test`) + `Test`) test("[[./test.org][Test]]", - `Test`) + `Test`) test("[[test.org][Test]]", - `Test`) + `Test`) test("[[path/to/test.org][Test]]", - `Test`) + `Test`) } func TestRender_Media(t *testing.T) { test := func(input, expected string) { - buffer, err := RenderString(markup.NewTestRenderContext("./relative-path"), input) + buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } test("[[file:../../.images/src/02/train.jpg]]", - ``) + ``) test("[[file:train.jpg]]", - ``) + ``) // With description. test("[[https://example.com][https://example.com/example.svg]]", @@ -91,7 +92,7 @@ func TestRender_Media(t *testing.T) { func TestRender_Source(t *testing.T) { test := func(input, expected string) { - buffer, err := RenderString(markup.NewTestRenderContext(), input) + buffer, err := orgmode.RenderString(markup.NewTestRenderContext(), input) assert.NoError(t, err) assert.Equal(t, strings.TrimSpace(expected), strings.TrimSpace(buffer)) } diff --git a/modules/markup/render.go b/modules/markup/render.go index 37a2a86687..79f1f473c2 100644 --- a/modules/markup/render.go +++ b/modules/markup/render.go @@ -8,6 +8,7 @@ import ( "fmt" "io" "net/url" + "strconv" "strings" "time" @@ -46,7 +47,7 @@ type RenderOptions struct { // user&repo, format&style®exp (for external issue pattern), teams&org (for mention) // RefTypeNameSubURL (for iframe&asciicast) // markupAllowShortIssuePattern - // markdownLineBreakStyle (comment, document) + // markdownNewLineHardBreak Metas map[string]string // used by external render. the router "/org/repo/render/..." will output the rendered content in a standalone page @@ -247,7 +248,8 @@ func Init(renderHelpFuncs *RenderHelperFuncs) { } func ComposeSimpleDocumentMetas() map[string]string { - return map[string]string{"markdownLineBreakStyle": "document"} + // TODO: there is no separate config option for "simple document" rendering, so temporarily use the same config as "repo file" + return map[string]string{"markdownNewLineHardBreak": strconv.FormatBool(setting.Markdown.RenderOptionsRepoFile.NewLineHardBreak)} } type TestRenderHelper struct { @@ -261,8 +263,14 @@ func (r *TestRenderHelper) IsCommitIDExisting(commitID string) bool { return strings.HasPrefix(commitID, "65f1bf2") //|| strings.HasPrefix(commitID, "88fc37a") } -func (r *TestRenderHelper) ResolveLink(link string, likeType LinkType) string { - return r.ctx.ResolveLinkRelative(r.BaseLink, "", link) +func (r *TestRenderHelper) ResolveLink(link, preferLinkType string) string { + linkType, link := ParseRenderedLink(link, preferLinkType) + switch linkType { + case LinkTypeRoot: + return r.ctx.ResolveLinkRoot(link) + default: + return r.ctx.ResolveLinkRelative(r.BaseLink, "", link) + } } var _ RenderHelper = (*TestRenderHelper)(nil) diff --git a/modules/markup/render_helper.go b/modules/markup/render_helper.go index 8ff0e7d6fb..b16f1189c5 100644 --- a/modules/markup/render_helper.go +++ b/modules/markup/render_helper.go @@ -10,13 +10,11 @@ import ( "code.gitea.io/gitea/modules/setting" ) -type LinkType string - const ( - LinkTypeApp LinkType = "app" // the link is relative to the AppSubURL - LinkTypeDefault LinkType = "default" // the link is relative to the default base (eg: repo link, or current ref tree path) - LinkTypeMedia LinkType = "media" // the link should be used to access media files (images, videos) - LinkTypeRaw LinkType = "raw" // not really useful, mainly for environment GITEA_PREFIX_RAW for external renders + LinkTypeDefault = "" + LinkTypeRoot = "/:root" // the link is relative to the AppSubURL(ROOT_URL) + LinkTypeMedia = "/:media" // the link should be used to access media files (images, videos) + LinkTypeRaw = "/:raw" // not really useful, mainly for environment GITEA_PREFIX_RAW for external renders ) type RenderHelper interface { @@ -27,7 +25,7 @@ type RenderHelper interface { // but not make processors to guess "is it rendering a comment or a wiki?" or "does it need to check commit ID?" IsCommitIDExisting(commitID string) bool - ResolveLink(link string, likeType LinkType) string + ResolveLink(link, preferLinkType string) string } // RenderHelperFuncs is used to decouple cycle-import @@ -51,7 +49,8 @@ func (r *SimpleRenderHelper) IsCommitIDExisting(commitID string) bool { return false } -func (r *SimpleRenderHelper) ResolveLink(link string, likeType LinkType) string { +func (r *SimpleRenderHelper) ResolveLink(link, preferLinkType string) string { + _, link = ParseRenderedLink(link, preferLinkType) return resolveLinkRelative(context.Background(), setting.AppSubURL+"/", "", link, false) } diff --git a/modules/markup/render_link.go b/modules/markup/render_link.go index b2e0699681..046544ce81 100644 --- a/modules/markup/render_link.go +++ b/modules/markup/render_link.go @@ -33,10 +33,24 @@ func resolveLinkRelative(ctx context.Context, base, cur, link string, absolute b return finalLink } -func (ctx *RenderContext) ResolveLinkRelative(base, cur, link string) (finalLink string) { +func (ctx *RenderContext) ResolveLinkRelative(base, cur, link string) string { + if strings.HasPrefix(link, "/:") { + setting.PanicInDevOrTesting("invalid link %q, forgot to cut?", link) + } return resolveLinkRelative(ctx, base, cur, link, ctx.RenderOptions.UseAbsoluteLink) } -func (ctx *RenderContext) ResolveLinkApp(link string) string { +func (ctx *RenderContext) ResolveLinkRoot(link string) string { return ctx.ResolveLinkRelative(setting.AppSubURL+"/", "", link) } + +func ParseRenderedLink(s, preferLinkType string) (linkType, link string) { + if strings.HasPrefix(s, "/:") { + p := strings.IndexByte(s[1:], '/') + if p == -1 { + return s, "" + } + return s[:p+1], s[p+2:] + } + return preferLinkType, s +} diff --git a/modules/optional/serialization_test.go b/modules/optional/serialization_test.go index 09a4bddea0..21d3ad8470 100644 --- a/modules/optional/serialization_test.go +++ b/modules/optional/serialization_test.go @@ -51,11 +51,11 @@ func TestOptionalToJson(t *testing.T) { t.Run(tc.name, func(t *testing.T) { b, err := json.Marshal(tc.obj) assert.NoError(t, err) - assert.EqualValues(t, tc.want, string(b), "gitea json module returned unexpected") + assert.Equal(t, tc.want, string(b), "gitea json module returned unexpected") b, err = std_json.Marshal(tc.obj) assert.NoError(t, err) - assert.EqualValues(t, tc.want, string(b), "std json module returned unexpected") + assert.Equal(t, tc.want, string(b), "std json module returned unexpected") }) } } @@ -89,12 +89,12 @@ func TestOptionalFromJson(t *testing.T) { var obj1 testSerializationStruct err := json.Unmarshal([]byte(tc.data), &obj1) assert.NoError(t, err) - assert.EqualValues(t, tc.want, obj1, "gitea json module returned unexpected") + assert.Equal(t, tc.want, obj1, "gitea json module returned unexpected") var obj2 testSerializationStruct err = std_json.Unmarshal([]byte(tc.data), &obj2) assert.NoError(t, err) - assert.EqualValues(t, tc.want, obj2, "std json module returned unexpected") + assert.Equal(t, tc.want, obj2, "std json module returned unexpected") }) } } @@ -135,7 +135,7 @@ optional_two_string: null t.Run(tc.name, func(t *testing.T) { b, err := yaml.Marshal(tc.obj) assert.NoError(t, err) - assert.EqualValues(t, tc.want, string(b), "yaml module returned unexpected") + assert.Equal(t, tc.want, string(b), "yaml module returned unexpected") }) } } @@ -184,7 +184,7 @@ optional_twostring: null var obj testSerializationStruct err := yaml.Unmarshal([]byte(tc.data), &obj) assert.NoError(t, err) - assert.EqualValues(t, tc.want, obj, "yaml module returned unexpected") + assert.Equal(t, tc.want, obj, "yaml module returned unexpected") }) } } diff --git a/modules/packages/goproxy/metadata.go b/modules/packages/goproxy/metadata.go index 40f7d20508..a67b149f4d 100644 --- a/modules/packages/goproxy/metadata.go +++ b/modules/packages/goproxy/metadata.go @@ -5,7 +5,6 @@ package goproxy import ( "archive/zip" - "fmt" "io" "path" "strings" @@ -88,7 +87,7 @@ func ParsePackage(r io.ReaderAt, size int64) (*Package, error) { return nil, ErrInvalidStructure } - p.GoMod = fmt.Sprintf("module %s", p.Name) + p.GoMod = "module " + p.Name return p, nil } diff --git a/modules/private/internal.go b/modules/private/internal.go index 35eed1d608..e599c6eb8e 100644 --- a/modules/private/internal.go +++ b/modules/private/internal.go @@ -6,7 +6,6 @@ package private import ( "context" "crypto/tls" - "fmt" "net" "net/http" "os" @@ -47,7 +46,7 @@ Ensure you are running in the correct environment or set the correct configurati req := httplib.NewRequest(url, method). SetContext(ctx). Header("X-Real-IP", getClientIP()). - Header("X-Gitea-Internal-Auth", fmt.Sprintf("Bearer %s", setting.InternalToken)). + Header("X-Gitea-Internal-Auth", "Bearer "+setting.InternalToken). SetTLSClientConfig(&tls.Config{ InsecureSkipVerify: true, ServerName: setting.Domain, diff --git a/modules/private/serv.go b/modules/private/serv.go index 2ccc6c1129..10e9f7995c 100644 --- a/modules/private/serv.go +++ b/modules/private/serv.go @@ -55,7 +55,7 @@ func ServCommand(ctx context.Context, keyID int64, ownerName, repoName string, m ) for _, verb := range verbs { if verb != "" { - reqURL += fmt.Sprintf("&verb=%s", url.QueryEscape(verb)) + reqURL += "&verb=" + url.QueryEscape(verb) } } req := newInternalRequestAPI(ctx, reqURL, "GET") diff --git a/modules/proxyprotocol/errors.go b/modules/proxyprotocol/errors.go index 5439a86bd8..f76c82b7f6 100644 --- a/modules/proxyprotocol/errors.go +++ b/modules/proxyprotocol/errors.go @@ -20,7 +20,7 @@ type ErrBadAddressType struct { } func (e *ErrBadAddressType) Error() string { - return fmt.Sprintf("Unexpected proxy header address type: %s", e.Address) + return "Unexpected proxy header address type: " + e.Address } // ErrBadRemote is an error demonstrating a bad proxy header with bad Remote diff --git a/modules/queue/base_test.go b/modules/queue/base_test.go index 73abf49091..1a96ac1e1d 100644 --- a/modules/queue/base_test.go +++ b/modules/queue/base_test.go @@ -21,7 +21,7 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error) _ = q.RemoveAll(ctx) cnt, err := q.Len(ctx) assert.NoError(t, err) - assert.EqualValues(t, 0, cnt) + assert.Equal(t, 0, cnt) // push the first item err = q.PushItem(ctx, []byte("foo")) @@ -29,7 +29,7 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error) cnt, err = q.Len(ctx) assert.NoError(t, err) - assert.EqualValues(t, 1, cnt) + assert.Equal(t, 1, cnt) // push a duplicate item err = q.PushItem(ctx, []byte("foo")) @@ -45,10 +45,10 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error) has, err := q.HasItem(ctx, []byte("foo")) assert.NoError(t, err) if !isUnique { - assert.EqualValues(t, 2, cnt) + assert.Equal(t, 2, cnt) assert.False(t, has) // non-unique queues don't check for duplicates } else { - assert.EqualValues(t, 1, cnt) + assert.Equal(t, 1, cnt) assert.True(t, has) } @@ -59,18 +59,18 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error) // pop the first item (and the duplicate if non-unique) it, err := q.PopItem(ctx) assert.NoError(t, err) - assert.EqualValues(t, "foo", string(it)) + assert.Equal(t, "foo", string(it)) if !isUnique { it, err = q.PopItem(ctx) assert.NoError(t, err) - assert.EqualValues(t, "foo", string(it)) + assert.Equal(t, "foo", string(it)) } // pop another item it, err = q.PopItem(ctx) assert.NoError(t, err) - assert.EqualValues(t, "bar", string(it)) + assert.Equal(t, "bar", string(it)) // pop an empty queue (timeout, cancel) ctxTimed, cancel := context.WithTimeout(ctx, 10*time.Millisecond) @@ -107,13 +107,13 @@ func testQueueBasic(t *testing.T, newFn func(cfg *BaseConfig) (baseQueue, error) // remove all cnt, err = q.Len(ctx) assert.NoError(t, err) - assert.EqualValues(t, cfg.Length, cnt) + assert.Equal(t, cfg.Length, cnt) _ = q.RemoveAll(ctx) cnt, err = q.Len(ctx) assert.NoError(t, err) - assert.EqualValues(t, 0, cnt) + assert.Equal(t, 0, cnt) }) } @@ -126,7 +126,7 @@ func TestBaseDummy(t *testing.T) { cnt, err := q.Len(ctx) assert.NoError(t, err) - assert.EqualValues(t, 0, cnt) + assert.Equal(t, 0, cnt) has, err := q.HasItem(ctx, []byte("foo")) assert.NoError(t, err) diff --git a/modules/queue/manager_test.go b/modules/queue/manager_test.go index f55ee85a22..fda498cc84 100644 --- a/modules/queue/manager_test.go +++ b/modules/queue/manager_test.go @@ -47,7 +47,7 @@ CONN_STR = redis:// assert.Equal(t, filepath.Join(setting.AppDataPath, "queues/common"), q.baseConfig.DataFullDir) assert.Equal(t, 100000, q.baseConfig.Length) assert.Equal(t, 20, q.batchLength) - assert.Equal(t, "", q.baseConfig.ConnStr) + assert.Empty(t, q.baseConfig.ConnStr) assert.Equal(t, "default_queue", q.baseConfig.QueueFullName) assert.Equal(t, "default_queue_unique", q.baseConfig.SetFullName) assert.NotZero(t, q.GetWorkerMaxNumber()) @@ -101,7 +101,7 @@ MAX_WORKERS = 123 assert.Equal(t, filepath.Join(setting.AppDataPath, "queues/dir2"), q2.baseConfig.DataFullDir) assert.Equal(t, 102, q2.baseConfig.Length) assert.Equal(t, 22, q2.batchLength) - assert.Equal(t, "", q2.baseConfig.ConnStr) + assert.Empty(t, q2.baseConfig.ConnStr) assert.Equal(t, "sub_q2", q2.baseConfig.QueueFullName) assert.Equal(t, "sub_q2_u2", q2.baseConfig.SetFullName) assert.Equal(t, 123, q2.GetWorkerMaxNumber()) diff --git a/modules/queue/workerqueue_test.go b/modules/queue/workerqueue_test.go index 0ca2be1d21..487c2f1a92 100644 --- a/modules/queue/workerqueue_test.go +++ b/modules/queue/workerqueue_test.go @@ -63,9 +63,9 @@ func TestWorkerPoolQueueUnhandled(t *testing.T) { ok := true for i := 0; i < queueSetting.Length; i++ { if i%2 == 0 { - ok = ok && assert.EqualValues(t, 2, m[i], "test %s: item %d", t.Name(), i) + ok = ok && assert.Equal(t, 2, m[i], "test %s: item %d", t.Name(), i) } else { - ok = ok && assert.EqualValues(t, 1, m[i], "test %s: item %d", t.Name(), i) + ok = ok && assert.Equal(t, 1, m[i], "test %s: item %d", t.Name(), i) } } if !ok { @@ -173,7 +173,7 @@ func testWorkerPoolQueuePersistence(t *testing.T, queueSetting setting.QueueSett assert.NotEmpty(t, tasksQ1) assert.NotEmpty(t, tasksQ2) - assert.EqualValues(t, testCount, len(tasksQ1)+len(tasksQ2)) + assert.Equal(t, testCount, len(tasksQ1)+len(tasksQ2)) } func TestWorkerPoolQueueActiveWorkers(t *testing.T) { @@ -191,13 +191,13 @@ func TestWorkerPoolQueueActiveWorkers(t *testing.T) { } time.Sleep(50 * time.Millisecond) - assert.EqualValues(t, 1, q.GetWorkerNumber()) - assert.EqualValues(t, 1, q.GetWorkerActiveNumber()) + assert.Equal(t, 1, q.GetWorkerNumber()) + assert.Equal(t, 1, q.GetWorkerActiveNumber()) time.Sleep(500 * time.Millisecond) - assert.EqualValues(t, 1, q.GetWorkerNumber()) - assert.EqualValues(t, 0, q.GetWorkerActiveNumber()) + assert.Equal(t, 1, q.GetWorkerNumber()) + assert.Equal(t, 0, q.GetWorkerActiveNumber()) time.Sleep(workerIdleDuration) - assert.EqualValues(t, 1, q.GetWorkerNumber()) // there is at least one worker after the queue begins working + assert.Equal(t, 1, q.GetWorkerNumber()) // there is at least one worker after the queue begins working stop() q, _ = newWorkerPoolQueueForTest("test-workpoolqueue", setting.QueueSettings{Type: "channel", BatchLength: 1, MaxWorkers: 3, Length: 100}, handler, false) @@ -207,13 +207,13 @@ func TestWorkerPoolQueueActiveWorkers(t *testing.T) { } time.Sleep(50 * time.Millisecond) - assert.EqualValues(t, 3, q.GetWorkerNumber()) - assert.EqualValues(t, 3, q.GetWorkerActiveNumber()) + assert.Equal(t, 3, q.GetWorkerNumber()) + assert.Equal(t, 3, q.GetWorkerActiveNumber()) time.Sleep(500 * time.Millisecond) - assert.EqualValues(t, 3, q.GetWorkerNumber()) - assert.EqualValues(t, 0, q.GetWorkerActiveNumber()) + assert.Equal(t, 3, q.GetWorkerNumber()) + assert.Equal(t, 0, q.GetWorkerActiveNumber()) time.Sleep(workerIdleDuration) - assert.EqualValues(t, 1, q.GetWorkerNumber()) // there is at least one worker after the queue begins working + assert.Equal(t, 1, q.GetWorkerNumber()) // there is at least one worker after the queue begins working stop() } @@ -240,13 +240,13 @@ func TestWorkerPoolQueueShutdown(t *testing.T) { } <-handlerCalled time.Sleep(200 * time.Millisecond) // wait for a while to make sure all workers are active - assert.EqualValues(t, 4, q.GetWorkerActiveNumber()) + assert.Equal(t, 4, q.GetWorkerActiveNumber()) stop() // stop triggers shutdown - assert.EqualValues(t, 0, q.GetWorkerActiveNumber()) + assert.Equal(t, 0, q.GetWorkerActiveNumber()) // no item was ever handled, so we still get all of them again q, _ = newWorkerPoolQueueForTest("test-workpoolqueue", qs, handler, false) - assert.EqualValues(t, 20, q.GetQueueItemNumber()) + assert.Equal(t, 20, q.GetQueueItemNumber()) } func TestWorkerPoolQueueWorkerIdleReset(t *testing.T) { diff --git a/modules/references/references_test.go b/modules/references/references_test.go index 1b6a968d6a..a15ae99f79 100644 --- a/modules/references/references_test.go +++ b/modules/references/references_test.go @@ -46,7 +46,7 @@ owner/repo!123456789 contentBytes := []byte(test) convertFullHTMLReferencesToShortRefs(re, &contentBytes) result := string(contentBytes) - assert.EqualValues(t, expect, result) + assert.Equal(t, expect, result) } func TestFindAllIssueReferences(t *testing.T) { @@ -283,9 +283,9 @@ func testFixtures(t *testing.T, fixtures []testFixture, context string) { } expref := rawToIssueReferenceList(expraw) refs := FindAllIssueReferencesMarkdown(fixture.input) - assert.EqualValues(t, expref, refs, "[%s] Failed to parse: {%s}", context, fixture.input) + assert.Equal(t, expref, refs, "[%s] Failed to parse: {%s}", context, fixture.input) rawrefs := findAllIssueReferencesMarkdown(fixture.input) - assert.EqualValues(t, expraw, rawrefs, "[%s] Failed to parse: {%s}", context, fixture.input) + assert.Equal(t, expraw, rawrefs, "[%s] Failed to parse: {%s}", context, fixture.input) } // Restore for other tests that may rely on the original value @@ -294,7 +294,7 @@ func testFixtures(t *testing.T, fixtures []testFixture, context string) { func TestFindAllMentions(t *testing.T) { res := FindAllMentionsBytes([]byte("@tasha, @mike; @lucy: @john")) - assert.EqualValues(t, []RefSpan{ + assert.Equal(t, []RefSpan{ {Start: 0, End: 6}, {Start: 8, End: 13}, {Start: 15, End: 20}, @@ -554,7 +554,7 @@ func TestParseCloseKeywords(t *testing.T) { res := pat.FindAllStringSubmatch(test.match, -1) assert.Len(t, res, 1) assert.Len(t, res[0], 2) - assert.EqualValues(t, test.expected, res[0][1]) + assert.Equal(t, test.expected, res[0][1]) } } } diff --git a/modules/regexplru/regexplru_test.go b/modules/regexplru/regexplru_test.go index 9c24b23fa9..4b539c31e9 100644 --- a/modules/regexplru/regexplru_test.go +++ b/modules/regexplru/regexplru_test.go @@ -18,9 +18,9 @@ func TestRegexpLru(t *testing.T) { assert.NoError(t, err) assert.True(t, r.MatchString("a")) - assert.EqualValues(t, 1, lruCache.Len()) + assert.Equal(t, 1, lruCache.Len()) _, err = GetCompiled("(") assert.Error(t, err) - assert.EqualValues(t, 2, lruCache.Len()) + assert.Equal(t, 2, lruCache.Len()) } diff --git a/modules/repository/branch_test.go b/modules/repository/branch_test.go index acf75a1ac0..ead28aa141 100644 --- a/modules/repository/branch_test.go +++ b/modules/repository/branch_test.go @@ -27,5 +27,5 @@ func TestSyncRepoBranches(t *testing.T) { assert.Equal(t, "sha1", repo.ObjectFormatName) branch, err := git_model.GetBranch(db.DefaultContext, 1, "master") assert.NoError(t, err) - assert.EqualValues(t, "master", branch.Name) + assert.Equal(t, "master", branch.Name) } diff --git a/modules/repository/commits_test.go b/modules/repository/commits_test.go index e8dbf0b4e9..6e407015c2 100644 --- a/modules/repository/commits_test.go +++ b/modules/repository/commits_test.go @@ -62,9 +62,9 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "user2", payloadCommits[0].Committer.UserName) assert.Equal(t, "User2", payloadCommits[0].Author.Name) assert.Equal(t, "user2", payloadCommits[0].Author.UserName) - assert.EqualValues(t, []string{}, payloadCommits[0].Added) - assert.EqualValues(t, []string{}, payloadCommits[0].Removed) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[0].Modified) + assert.Equal(t, []string{}, payloadCommits[0].Added) + assert.Equal(t, []string{}, payloadCommits[0].Removed) + assert.Equal(t, []string{"readme.md"}, payloadCommits[0].Modified) assert.Equal(t, "27566bd", payloadCommits[1].ID) assert.Equal(t, "good signed commit (with not yet validated email)", payloadCommits[1].Message) @@ -73,9 +73,9 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "user2", payloadCommits[1].Committer.UserName) assert.Equal(t, "User2", payloadCommits[1].Author.Name) assert.Equal(t, "user2", payloadCommits[1].Author.UserName) - assert.EqualValues(t, []string{}, payloadCommits[1].Added) - assert.EqualValues(t, []string{}, payloadCommits[1].Removed) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[1].Modified) + assert.Equal(t, []string{}, payloadCommits[1].Added) + assert.Equal(t, []string{}, payloadCommits[1].Removed) + assert.Equal(t, []string{"readme.md"}, payloadCommits[1].Modified) assert.Equal(t, "5099b81", payloadCommits[2].ID) assert.Equal(t, "good signed commit", payloadCommits[2].Message) @@ -84,9 +84,9 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "user2", payloadCommits[2].Committer.UserName) assert.Equal(t, "User2", payloadCommits[2].Author.Name) assert.Equal(t, "user2", payloadCommits[2].Author.UserName) - assert.EqualValues(t, []string{"readme.md"}, payloadCommits[2].Added) - assert.EqualValues(t, []string{}, payloadCommits[2].Removed) - assert.EqualValues(t, []string{}, payloadCommits[2].Modified) + assert.Equal(t, []string{"readme.md"}, payloadCommits[2].Added) + assert.Equal(t, []string{}, payloadCommits[2].Removed) + assert.Equal(t, []string{}, payloadCommits[2].Modified) assert.Equal(t, "69554a6", headCommit.ID) assert.Equal(t, "not signed commit", headCommit.Message) @@ -95,9 +95,9 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) { assert.Equal(t, "user2", headCommit.Committer.UserName) assert.Equal(t, "User2", headCommit.Author.Name) assert.Equal(t, "user2", headCommit.Author.UserName) - assert.EqualValues(t, []string{}, headCommit.Added) - assert.EqualValues(t, []string{}, headCommit.Removed) - assert.EqualValues(t, []string{"readme.md"}, headCommit.Modified) + assert.Equal(t, []string{}, headCommit.Added) + assert.Equal(t, []string{}, headCommit.Removed) + assert.Equal(t, []string{"readme.md"}, headCommit.Modified) } func TestPushCommits_AvatarLink(t *testing.T) { diff --git a/modules/repository/create_test.go b/modules/repository/create_test.go index a9151482b4..e1f981ba3c 100644 --- a/modules/repository/create_test.go +++ b/modules/repository/create_test.go @@ -41,5 +41,5 @@ func TestGetDirectorySize(t *testing.T) { size, err := getDirectorySize(repo.RepoPath()) assert.NoError(t, err) repo.Size = 8165 // real size on the disk - assert.EqualValues(t, repo.Size, size) + assert.Equal(t, repo.Size, size) } diff --git a/modules/repository/env.go b/modules/repository/env.go index e4f32092fc..78e06f86fb 100644 --- a/modules/repository/env.go +++ b/modules/repository/env.go @@ -4,8 +4,8 @@ package repository import ( - "fmt" "os" + "strconv" "strings" repo_model "code.gitea.io/gitea/models/repo" @@ -72,9 +72,9 @@ func FullPushingEnvironment(author, committer *user_model.User, repo *repo_model EnvRepoUsername+"="+repo.OwnerName, EnvRepoIsWiki+"="+isWiki, EnvPusherName+"="+committer.Name, - EnvPusherID+"="+fmt.Sprintf("%d", committer.ID), - EnvRepoID+"="+fmt.Sprintf("%d", repo.ID), - EnvPRID+"="+fmt.Sprintf("%d", prID), + EnvPusherID+"="+strconv.FormatInt(committer.ID, 10), + EnvRepoID+"="+strconv.FormatInt(repo.ID, 10), + EnvPRID+"="+strconv.FormatInt(prID, 10), EnvAppURL+"="+setting.AppURL, "SSH_ORIGINAL_COMMAND=gitea-internal", ) diff --git a/modules/repository/init_test.go b/modules/repository/init_test.go index 227efdc1db..1fa928105c 100644 --- a/modules/repository/init_test.go +++ b/modules/repository/init_test.go @@ -14,17 +14,17 @@ func TestMergeCustomLabels(t *testing.T) { all: []string{"a", "a.yaml", "a.yml"}, custom: nil, }) - assert.EqualValues(t, []string{"a.yaml"}, files, "yaml file should win") + assert.Equal(t, []string{"a.yaml"}, files, "yaml file should win") files = mergeCustomLabelFiles(optionFileList{ all: []string{"a", "a.yaml"}, custom: []string{"a"}, }) - assert.EqualValues(t, []string{"a"}, files, "custom file should win") + assert.Equal(t, []string{"a"}, files, "custom file should win") files = mergeCustomLabelFiles(optionFileList{ all: []string{"a", "a.yml", "a.yaml"}, custom: []string{"a", "a.yml"}, }) - assert.EqualValues(t, []string{"a.yml"}, files, "custom yml file should win if no yaml") + assert.Equal(t, []string{"a.yml"}, files, "custom yml file should win if no yaml") } diff --git a/modules/repository/repo.go b/modules/repository/repo.go index 97b0343381..bc147a4dd5 100644 --- a/modules/repository/repo.go +++ b/modules/repository/repo.go @@ -126,7 +126,7 @@ func PushUpdateAddTag(ctx context.Context, repo *repo_model.Repository, gitRepo if err != nil { return fmt.Errorf("unable to GetTag: %w", err) } - commit, err := tag.Commit(gitRepo) + commit, err := gitRepo.GetTagCommit(tag.Name) if err != nil { return fmt.Errorf("unable to get tag Commit: %w", err) } diff --git a/modules/repository/repo_test.go b/modules/repository/repo_test.go index f3e7be6d7d..f79a79ccbd 100644 --- a/modules/repository/repo_test.go +++ b/modules/repository/repo_test.go @@ -63,7 +63,7 @@ func Test_calcSync(t *testing.T) { inserts, deletes, updates := calcSync(gitTags, dbReleases) if assert.Len(t, inserts, 1, "inserts") { - assert.EqualValues(t, *gitTags[2], *inserts[0], "inserts equal") + assert.Equal(t, *gitTags[2], *inserts[0], "inserts equal") } if assert.Len(t, deletes, 1, "deletes") { @@ -71,6 +71,6 @@ func Test_calcSync(t *testing.T) { } if assert.Len(t, updates, 1, "updates") { - assert.EqualValues(t, *gitTags[1], *updates[0], "updates equal") + assert.Equal(t, *gitTags[1], *updates[0], "updates equal") } } diff --git a/modules/setting/actions_test.go b/modules/setting/actions_test.go index 3645a3f5da..353cc657fa 100644 --- a/modules/setting/actions_test.go +++ b/modules/setting/actions_test.go @@ -21,9 +21,9 @@ func Test_getStorageInheritNameSectionTypeForActions(t *testing.T) { assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "minio", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) iniStr = ` [storage.actions_log] @@ -34,9 +34,9 @@ STORAGE_TYPE = minio assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "minio", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) assert.EqualValues(t, "local", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) + assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) iniStr = ` [storage.actions_log] @@ -50,9 +50,9 @@ STORAGE_TYPE = minio assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "minio", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) assert.EqualValues(t, "local", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) + assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) iniStr = ` [storage.actions_artifacts] @@ -66,9 +66,9 @@ STORAGE_TYPE = minio assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "local", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) + assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) iniStr = ` [storage.actions_artifacts] @@ -82,9 +82,9 @@ STORAGE_TYPE = minio assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "local", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) + assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) + assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) iniStr = `` cfg, err = NewConfigProviderFromData(iniStr) @@ -92,9 +92,9 @@ STORAGE_TYPE = minio assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "local", Actions.LogStorage.Type) - assert.EqualValues(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) + assert.Equal(t, "actions_log", filepath.Base(Actions.LogStorage.Path)) assert.EqualValues(t, "local", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) + assert.Equal(t, "actions_artifacts", filepath.Base(Actions.ArtifactStorage.Path)) } func Test_getDefaultActionsURLForActions(t *testing.T) { @@ -175,7 +175,7 @@ DEFAULT_ACTIONS_URL = gitea if !tt.wantErr(t, loadActionsFrom(cfg)) { return } - assert.EqualValues(t, tt.wantURL, Actions.DefaultActionsURL.URL()) + assert.Equal(t, tt.wantURL, Actions.DefaultActionsURL.URL()) }) } } diff --git a/modules/setting/attachment_test.go b/modules/setting/attachment_test.go index 3e8d2da4d9..c566dfa60c 100644 --- a/modules/setting/attachment_test.go +++ b/modules/setting/attachment_test.go @@ -25,9 +25,9 @@ MINIO_ENDPOINT = my_minio:9000 assert.NoError(t, loadAttachmentFrom(cfg)) assert.EqualValues(t, "minio", Attachment.Storage.Type) - assert.EqualValues(t, "my_minio:9000", Attachment.Storage.MinioConfig.Endpoint) - assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "my_minio:9000", Attachment.Storage.MinioConfig.Endpoint) + assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) } func Test_getStorageTypeSectionOverridesStorageSection(t *testing.T) { @@ -47,8 +47,8 @@ MINIO_BUCKET = gitea assert.NoError(t, loadAttachmentFrom(cfg)) assert.EqualValues(t, "minio", Attachment.Storage.Type) - assert.EqualValues(t, "gitea-minio", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-minio", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) } func Test_getStorageSpecificOverridesStorage(t *testing.T) { @@ -69,8 +69,8 @@ STORAGE_TYPE = local assert.NoError(t, loadAttachmentFrom(cfg)) assert.EqualValues(t, "minio", Attachment.Storage.Type) - assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) } func Test_getStorageGetDefaults(t *testing.T) { @@ -80,7 +80,7 @@ func Test_getStorageGetDefaults(t *testing.T) { assert.NoError(t, loadAttachmentFrom(cfg)) // default storage is local, so bucket is empty - assert.EqualValues(t, "", Attachment.Storage.MinioConfig.Bucket) + assert.Empty(t, Attachment.Storage.MinioConfig.Bucket) } func Test_getStorageInheritNameSectionType(t *testing.T) { @@ -115,7 +115,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := Attachment.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) } func Test_AttachmentStorage1(t *testing.T) { @@ -128,6 +128,6 @@ STORAGE_TYPE = minio assert.NoError(t, loadAttachmentFrom(cfg)) assert.EqualValues(t, "minio", Attachment.Storage.Type) - assert.EqualValues(t, "gitea", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) } diff --git a/modules/setting/config_env_test.go b/modules/setting/config_env_test.go index 7d07c479a1..217ea53860 100644 --- a/modules/setting/config_env_test.go +++ b/modules/setting/config_env_test.go @@ -28,8 +28,8 @@ func TestDecodeEnvSectionKey(t *testing.T) { ok, section, key = decodeEnvSectionKey("SEC") assert.False(t, ok) - assert.Equal(t, "", section) - assert.Equal(t, "", key) + assert.Empty(t, section) + assert.Empty(t, key) } func TestDecodeEnvironmentKey(t *testing.T) { @@ -38,19 +38,19 @@ func TestDecodeEnvironmentKey(t *testing.T) { ok, section, key, file := decodeEnvironmentKey(prefix, suffix, "SEC__KEY") assert.False(t, ok) - assert.Equal(t, "", section) - assert.Equal(t, "", key) + assert.Empty(t, section) + assert.Empty(t, key) assert.False(t, file) ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC") assert.False(t, ok) - assert.Equal(t, "", section) - assert.Equal(t, "", key) + assert.Empty(t, section) + assert.Empty(t, key) assert.False(t, file) ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA____KEY") assert.True(t, ok) - assert.Equal(t, "", section) + assert.Empty(t, section) assert.Equal(t, "KEY", key) assert.False(t, file) @@ -64,8 +64,8 @@ func TestDecodeEnvironmentKey(t *testing.T) { // but it could be fixed in the future by adding a new suffix like "__VALUE" (no such key VALUE is used in Gitea either) ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__FILE") assert.False(t, ok) - assert.Equal(t, "", section) - assert.Equal(t, "", key) + assert.Empty(t, section) + assert.Empty(t, key) assert.True(t, file) ok, section, key, file = decodeEnvironmentKey(prefix, suffix, "GITEA__SEC__KEY__FILE") diff --git a/modules/setting/config_provider.go b/modules/setting/config_provider.go index 3138f8a63e..a0c53a1032 100644 --- a/modules/setting/config_provider.go +++ b/modules/setting/config_provider.go @@ -26,6 +26,7 @@ type ConfigKey interface { In(defaultVal string, candidates []string) string String() string Strings(delim string) []string + Bool() (bool, error) MustString(defaultVal string) string MustBool(defaultVal ...bool) bool @@ -257,7 +258,7 @@ func (p *iniConfigProvider) Save() error { } filename := p.file if filename == "" { - return fmt.Errorf("config file path must not be empty") + return errors.New("config file path must not be empty") } if p.loadedFromEmpty { if err := os.MkdirAll(filepath.Dir(filename), os.ModePerm); err != nil { diff --git a/modules/setting/config_provider_test.go b/modules/setting/config_provider_test.go index a666d124c7..63121f0074 100644 --- a/modules/setting/config_provider_test.go +++ b/modules/setting/config_provider_test.go @@ -62,17 +62,17 @@ key = 123 // test default behavior assert.Equal(t, "123", ConfigSectionKeyString(sec, "key")) - assert.Equal(t, "", ConfigSectionKeyString(secSub, "key")) + assert.Empty(t, ConfigSectionKeyString(secSub, "key")) assert.Equal(t, "def", ConfigSectionKeyString(secSub, "key", "def")) assert.Equal(t, "123", ConfigInheritedKeyString(secSub, "key")) // Workaround for ini package's BuggyKeyOverwritten behavior - assert.Equal(t, "", ConfigSectionKeyString(sec, "empty")) - assert.Equal(t, "", ConfigSectionKeyString(secSub, "empty")) + assert.Empty(t, ConfigSectionKeyString(sec, "empty")) + assert.Empty(t, ConfigSectionKeyString(secSub, "empty")) assert.Equal(t, "def", ConfigInheritedKey(secSub, "empty").MustString("def")) assert.Equal(t, "def", ConfigInheritedKey(secSub, "empty").MustString("xyz")) - assert.Equal(t, "", ConfigSectionKeyString(sec, "empty")) + assert.Empty(t, ConfigSectionKeyString(sec, "empty")) assert.Equal(t, "def", ConfigSectionKeyString(secSub, "empty")) } diff --git a/modules/setting/cron_test.go b/modules/setting/cron_test.go index 55244d7075..39a228068a 100644 --- a/modules/setting/cron_test.go +++ b/modules/setting/cron_test.go @@ -38,6 +38,6 @@ EXTEND = true _, err = getCronSettings(cfg, "test", extended) assert.NoError(t, err) assert.True(t, extended.Base) - assert.EqualValues(t, "white rabbit", extended.Second) + assert.Equal(t, "white rabbit", extended.Second) assert.True(t, extended.Extend) } diff --git a/modules/setting/git_test.go b/modules/setting/git_test.go index 441c514d8c..818bcf9df6 100644 --- a/modules/setting/git_test.go +++ b/modules/setting/git_test.go @@ -23,8 +23,8 @@ a.b = 1 `) assert.NoError(t, err) loadGitFrom(cfg) - assert.EqualValues(t, "1", GitConfig.Options["a.b"]) - assert.EqualValues(t, "histogram", GitConfig.Options["diff.algorithm"]) + assert.Equal(t, "1", GitConfig.Options["a.b"]) + assert.Equal(t, "histogram", GitConfig.Options["diff.algorithm"]) cfg, err = NewConfigProviderFromData(` [git.config] @@ -32,7 +32,7 @@ diff.algorithm = other `) assert.NoError(t, err) loadGitFrom(cfg) - assert.EqualValues(t, "other", GitConfig.Options["diff.algorithm"]) + assert.Equal(t, "other", GitConfig.Options["diff.algorithm"]) } func TestGitReflog(t *testing.T) { @@ -48,8 +48,8 @@ func TestGitReflog(t *testing.T) { assert.NoError(t, err) loadGitFrom(cfg) - assert.EqualValues(t, "true", GitConfig.GetOption("core.logAllRefUpdates")) - assert.EqualValues(t, "90", GitConfig.GetOption("gc.reflogExpire")) + assert.Equal(t, "true", GitConfig.GetOption("core.logAllRefUpdates")) + assert.Equal(t, "90", GitConfig.GetOption("gc.reflogExpire")) // custom reflog config by legacy options cfg, err = NewConfigProviderFromData(` @@ -60,6 +60,6 @@ EXPIRATION = 123 assert.NoError(t, err) loadGitFrom(cfg) - assert.EqualValues(t, "false", GitConfig.GetOption("core.logAllRefUpdates")) - assert.EqualValues(t, "123", GitConfig.GetOption("gc.reflogExpire")) + assert.Equal(t, "false", GitConfig.GetOption("core.logAllRefUpdates")) + assert.Equal(t, "123", GitConfig.GetOption("gc.reflogExpire")) } diff --git a/modules/setting/global_lock_test.go b/modules/setting/global_lock_test.go index 5eeb275523..5e15eb3483 100644 --- a/modules/setting/global_lock_test.go +++ b/modules/setting/global_lock_test.go @@ -16,7 +16,7 @@ func TestLoadGlobalLockConfig(t *testing.T) { assert.NoError(t, err) loadGlobalLockFrom(cfg) - assert.EqualValues(t, "memory", GlobalLock.ServiceType) + assert.Equal(t, "memory", GlobalLock.ServiceType) }) t.Run("RedisGlobalLockConfig", func(t *testing.T) { @@ -29,7 +29,7 @@ SERVICE_CONN_STR = addrs=127.0.0.1:6379 db=0 assert.NoError(t, err) loadGlobalLockFrom(cfg) - assert.EqualValues(t, "redis", GlobalLock.ServiceType) - assert.EqualValues(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr) + assert.Equal(t, "redis", GlobalLock.ServiceType) + assert.Equal(t, "addrs=127.0.0.1:6379 db=0", GlobalLock.ServiceConnStr) }) } diff --git a/modules/setting/incoming_email.go b/modules/setting/incoming_email.go index bf81f292a2..4e433dde60 100644 --- a/modules/setting/incoming_email.go +++ b/modules/setting/incoming_email.go @@ -4,6 +4,7 @@ package setting import ( + "errors" "fmt" "net/mail" "strings" @@ -50,7 +51,7 @@ func checkReplyToAddress() error { } if parsed.Name != "" { - return fmt.Errorf("name must not be set") + return errors.New("name must not be set") } c := strings.Count(IncomingEmail.ReplyToAddress, IncomingEmail.TokenPlaceholder) diff --git a/modules/setting/lfs_test.go b/modules/setting/lfs_test.go index d27dd7c5bf..1b829d8839 100644 --- a/modules/setting/lfs_test.go +++ b/modules/setting/lfs_test.go @@ -19,7 +19,7 @@ func Test_getStorageInheritNameSectionTypeForLFS(t *testing.T) { assert.NoError(t, loadLFSFrom(cfg)) assert.EqualValues(t, "minio", LFS.Storage.Type) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) iniStr = ` [server] @@ -54,7 +54,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadLFSFrom(cfg)) assert.EqualValues(t, "minio", LFS.Storage.Type) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) iniStr = ` [lfs] @@ -68,7 +68,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadLFSFrom(cfg)) assert.EqualValues(t, "minio", LFS.Storage.Type) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) iniStr = ` [lfs] @@ -83,7 +83,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadLFSFrom(cfg)) assert.EqualValues(t, "minio", LFS.Storage.Type) - assert.EqualValues(t, "my_lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "my_lfs/", LFS.Storage.MinioConfig.BasePath) } func Test_LFSStorage1(t *testing.T) { @@ -96,8 +96,8 @@ STORAGE_TYPE = minio assert.NoError(t, loadLFSFrom(cfg)) assert.EqualValues(t, "minio", LFS.Storage.Type) - assert.EqualValues(t, "gitea", LFS.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", LFS.Storage.MinioConfig.Bucket) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) } func Test_LFSClientServerConfigs(t *testing.T) { @@ -112,9 +112,9 @@ BATCH_SIZE = 0 assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, 100, LFS.MaxBatchSize) - assert.EqualValues(t, 20, LFSClient.BatchSize) - assert.EqualValues(t, 8, LFSClient.BatchOperationConcurrency) + assert.Equal(t, 100, LFS.MaxBatchSize) + assert.Equal(t, 20, LFSClient.BatchSize) + assert.Equal(t, 8, LFSClient.BatchOperationConcurrency) iniStr = ` [lfs_client] @@ -125,6 +125,6 @@ BATCH_OPERATION_CONCURRENCY = 10 assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, 50, LFSClient.BatchSize) - assert.EqualValues(t, 10, LFSClient.BatchOperationConcurrency) + assert.Equal(t, 50, LFSClient.BatchSize) + assert.Equal(t, 10, LFSClient.BatchOperationConcurrency) } diff --git a/modules/setting/mailer_test.go b/modules/setting/mailer_test.go index fbabf11378..ceef35b051 100644 --- a/modules/setting/mailer_test.go +++ b/modules/setting/mailer_test.go @@ -34,8 +34,8 @@ func Test_loadMailerFrom(t *testing.T) { // Check mailer setting loadMailerFrom(cfg) - assert.EqualValues(t, kase.SMTPAddr, MailService.SMTPAddr) - assert.EqualValues(t, kase.SMTPPort, MailService.SMTPPort) + assert.Equal(t, kase.SMTPAddr, MailService.SMTPAddr) + assert.Equal(t, kase.SMTPPort, MailService.SMTPPort) }) } } diff --git a/modules/setting/markup.go b/modules/setting/markup.go index dfce8afa77..3bd368f831 100644 --- a/modules/setting/markup.go +++ b/modules/setting/markup.go @@ -8,6 +8,7 @@ import ( "strings" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/util" ) // ExternalMarkupRenderers represents the external markup renderers @@ -23,18 +24,33 @@ const ( RenderContentModeIframe = "iframe" ) +type MarkdownRenderOptions struct { + NewLineHardBreak bool + ShortIssuePattern bool // Actually it is a "markup" option because it is used in "post processor" +} + +type MarkdownMathCodeBlockOptions struct { + ParseInlineDollar bool + ParseInlineParentheses bool + ParseBlockDollar bool + ParseBlockSquareBrackets bool +} + // Markdown settings var Markdown = struct { - EnableHardLineBreakInComments bool - EnableHardLineBreakInDocuments bool - CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"` - FileExtensions []string - EnableMath bool + RenderOptionsComment MarkdownRenderOptions `ini:"-"` + RenderOptionsWiki MarkdownRenderOptions `ini:"-"` + RenderOptionsRepoFile MarkdownRenderOptions `ini:"-"` + + CustomURLSchemes []string `ini:"CUSTOM_URL_SCHEMES"` // Actually it is a "markup" option because it is used in "post processor" + FileExtensions []string + + EnableMath bool + MathCodeBlockDetection []string + MathCodeBlockOptions MarkdownMathCodeBlockOptions `ini:"-"` }{ - EnableHardLineBreakInComments: true, - EnableHardLineBreakInDocuments: false, - FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd,.livemd", ","), - EnableMath: true, + FileExtensions: strings.Split(".md,.markdown,.mdown,.mkd,.livemd", ","), + EnableMath: true, } // MarkupRenderer defines the external parser configured in ini @@ -60,6 +76,56 @@ type MarkupSanitizerRule struct { func loadMarkupFrom(rootCfg ConfigProvider) { mustMapSetting(rootCfg, "markdown", &Markdown) + const none = "none" + + const renderOptionShortIssuePattern = "short-issue-pattern" + const renderOptionNewLineHardBreak = "new-line-hard-break" + cfgMarkdown := rootCfg.Section("markdown") + parseMarkdownRenderOptions := func(key string, defaults []string) (ret MarkdownRenderOptions) { + options := cfgMarkdown.Key(key).Strings(",") + options = util.IfEmpty(options, defaults) + for _, opt := range options { + switch opt { + case renderOptionShortIssuePattern: + ret.ShortIssuePattern = true + case renderOptionNewLineHardBreak: + ret.NewLineHardBreak = true + case none: + ret = MarkdownRenderOptions{} + case "": + default: + log.Error("Unknown markdown render option in %s: %s", key, opt) + } + } + return ret + } + Markdown.RenderOptionsComment = parseMarkdownRenderOptions("RENDER_OPTIONS_COMMENT", []string{renderOptionShortIssuePattern, renderOptionNewLineHardBreak}) + Markdown.RenderOptionsWiki = parseMarkdownRenderOptions("RENDER_OPTIONS_WIKI", []string{renderOptionShortIssuePattern}) + Markdown.RenderOptionsRepoFile = parseMarkdownRenderOptions("RENDER_OPTIONS_REPO_FILE", nil) + + const mathCodeInlineDollar = "inline-dollar" + const mathCodeInlineParentheses = "inline-parentheses" + const mathCodeBlockDollar = "block-dollar" + const mathCodeBlockSquareBrackets = "block-square-brackets" + Markdown.MathCodeBlockDetection = util.IfEmpty(Markdown.MathCodeBlockDetection, []string{mathCodeInlineDollar, mathCodeBlockDollar}) + Markdown.MathCodeBlockOptions = MarkdownMathCodeBlockOptions{} + for _, s := range Markdown.MathCodeBlockDetection { + switch s { + case mathCodeInlineDollar: + Markdown.MathCodeBlockOptions.ParseInlineDollar = true + case mathCodeInlineParentheses: + Markdown.MathCodeBlockOptions.ParseInlineParentheses = true + case mathCodeBlockDollar: + Markdown.MathCodeBlockOptions.ParseBlockDollar = true + case mathCodeBlockSquareBrackets: + Markdown.MathCodeBlockOptions.ParseBlockSquareBrackets = true + case none: + Markdown.MathCodeBlockOptions = MarkdownMathCodeBlockOptions{} + case "": + default: + log.Error("Unknown math code block detection option: %s", s) + } + } MermaidMaxSourceCharacters = rootCfg.Section("markup").Key("MERMAID_MAX_SOURCE_CHARACTERS").MustInt(5000) ExternalMarkupRenderers = make([]*MarkupRenderer, 0, 10) diff --git a/modules/setting/markup_test.go b/modules/setting/markup_test.go new file mode 100644 index 0000000000..c47a38ce15 --- /dev/null +++ b/modules/setting/markup_test.go @@ -0,0 +1,51 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package setting + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestLoadMarkup(t *testing.T) { + cfg, _ := NewConfigProviderFromData(``) + loadMarkupFrom(cfg) + assert.Equal(t, MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseBlockDollar: true}, Markdown.MathCodeBlockOptions) + assert.Equal(t, MarkdownRenderOptions{NewLineHardBreak: true, ShortIssuePattern: true}, Markdown.RenderOptionsComment) + assert.Equal(t, MarkdownRenderOptions{ShortIssuePattern: true}, Markdown.RenderOptionsWiki) + assert.Equal(t, MarkdownRenderOptions{}, Markdown.RenderOptionsRepoFile) + + t.Run("Math", func(t *testing.T) { + cfg, _ = NewConfigProviderFromData(` +[markdown] +MATH_CODE_BLOCK_DETECTION = none +`) + loadMarkupFrom(cfg) + assert.Equal(t, MarkdownMathCodeBlockOptions{}, Markdown.MathCodeBlockOptions) + + cfg, _ = NewConfigProviderFromData(` +[markdown] +MATH_CODE_BLOCK_DETECTION = inline-dollar, inline-parentheses, block-dollar, block-square-brackets +`) + loadMarkupFrom(cfg) + assert.Equal(t, MarkdownMathCodeBlockOptions{ParseInlineDollar: true, ParseInlineParentheses: true, ParseBlockDollar: true, ParseBlockSquareBrackets: true}, Markdown.MathCodeBlockOptions) + }) + + t.Run("Render", func(t *testing.T) { + cfg, _ = NewConfigProviderFromData(` +[markdown] +RENDER_OPTIONS_COMMENT = none +`) + loadMarkupFrom(cfg) + assert.Equal(t, MarkdownRenderOptions{}, Markdown.RenderOptionsComment) + + cfg, _ = NewConfigProviderFromData(` +[markdown] +RENDER_OPTIONS_REPO_FILE = short-issue-pattern, new-line-hard-break +`) + loadMarkupFrom(cfg) + assert.Equal(t, MarkdownRenderOptions{NewLineHardBreak: true, ShortIssuePattern: true}, Markdown.RenderOptionsRepoFile) + }) +} diff --git a/modules/setting/oauth2_test.go b/modules/setting/oauth2_test.go index d0e5ccf13d..c6e66cad02 100644 --- a/modules/setting/oauth2_test.go +++ b/modules/setting/oauth2_test.go @@ -31,7 +31,7 @@ JWT_SECRET = BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB actual := GetGeneralTokenSigningSecret() expected, _ := generate.DecodeJwtSecretBase64("BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB") assert.Len(t, actual, 32) - assert.EqualValues(t, expected, actual) + assert.Equal(t, expected, actual) } func TestGetGeneralSigningSecretSave(t *testing.T) { diff --git a/modules/setting/packages_test.go b/modules/setting/packages_test.go index 87de276041..47378f35ad 100644 --- a/modules/setting/packages_test.go +++ b/modules/setting/packages_test.go @@ -41,7 +41,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "minio", Packages.Storage.Type) - assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath) + assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath) // we can also configure packages storage directly iniStr = ` @@ -53,7 +53,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "minio", Packages.Storage.Type) - assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath) + assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath) // or we can indicate the storage type in the packages section iniStr = ` @@ -68,7 +68,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "minio", Packages.Storage.Type) - assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath) + assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath) // or we can indicate the storage type and minio base path in the packages section iniStr = ` @@ -84,7 +84,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "minio", Packages.Storage.Type) - assert.EqualValues(t, "my_packages/", Packages.Storage.MinioConfig.BasePath) + assert.Equal(t, "my_packages/", Packages.Storage.MinioConfig.BasePath) } func Test_PackageStorage1(t *testing.T) { @@ -109,8 +109,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := Packages.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) - assert.EqualValues(t, "packages/", storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "packages/", storage.MinioConfig.BasePath) assert.True(t, storage.MinioConfig.ServeDirect) } @@ -136,8 +136,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := Packages.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) - assert.EqualValues(t, "packages/", storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "packages/", storage.MinioConfig.BasePath) assert.True(t, storage.MinioConfig.ServeDirect) } @@ -164,8 +164,8 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := Packages.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) - assert.EqualValues(t, "my_packages/", storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "my_packages/", storage.MinioConfig.BasePath) assert.True(t, storage.MinioConfig.ServeDirect) } @@ -192,7 +192,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := Packages.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) - assert.EqualValues(t, "my_packages/", storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "my_packages/", storage.MinioConfig.BasePath) assert.True(t, storage.MinioConfig.ServeDirect) } diff --git a/modules/setting/repository_archive_test.go b/modules/setting/repository_archive_test.go index a0f91f0da1..d5b95272d6 100644 --- a/modules/setting/repository_archive_test.go +++ b/modules/setting/repository_archive_test.go @@ -20,7 +20,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "minio", RepoArchive.Storage.Type) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) // we can also configure packages storage directly iniStr = ` @@ -32,7 +32,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "minio", RepoArchive.Storage.Type) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) // or we can indicate the storage type in the packages section iniStr = ` @@ -47,7 +47,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "minio", RepoArchive.Storage.Type) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) // or we can indicate the storage type and minio base path in the packages section iniStr = ` @@ -63,7 +63,7 @@ STORAGE_TYPE = minio assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "minio", RepoArchive.Storage.Type) - assert.EqualValues(t, "my_archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "my_archive/", RepoArchive.Storage.MinioConfig.BasePath) } func Test_RepoArchiveStorage(t *testing.T) { @@ -85,7 +85,7 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage := RepoArchive.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) iniStr = ` ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -107,5 +107,5 @@ MINIO_SECRET_ACCESS_KEY = correct_key storage = RepoArchive.Storage assert.EqualValues(t, "minio", storage.Type) - assert.EqualValues(t, "gitea", storage.MinioConfig.Bucket) + assert.Equal(t, "gitea", storage.MinioConfig.Bucket) } diff --git a/modules/setting/service.go b/modules/setting/service.go index 8c1843eeb7..d9535efec6 100644 --- a/modules/setting/service.go +++ b/modules/setting/service.go @@ -43,7 +43,8 @@ var Service = struct { ShowRegistrationButton bool EnablePasswordSignInForm bool ShowMilestonesDashboardPage bool - RequireSignInView bool + RequireSignInViewStrict bool + BlockAnonymousAccessExpensive bool EnableNotifyMail bool EnableBasicAuth bool EnablePasskeyAuth bool @@ -159,7 +160,18 @@ func loadServiceFrom(rootCfg ConfigProvider) { Service.EmailDomainBlockList = CompileEmailGlobList(sec, "EMAIL_DOMAIN_BLOCKLIST") Service.ShowRegistrationButton = sec.Key("SHOW_REGISTRATION_BUTTON").MustBool(!(Service.DisableRegistration || Service.AllowOnlyExternalRegistration)) Service.ShowMilestonesDashboardPage = sec.Key("SHOW_MILESTONES_DASHBOARD_PAGE").MustBool(true) - Service.RequireSignInView = sec.Key("REQUIRE_SIGNIN_VIEW").MustBool() + + // boolean values are considered as "strict" + var err error + Service.RequireSignInViewStrict, err = sec.Key("REQUIRE_SIGNIN_VIEW").Bool() + if s := sec.Key("REQUIRE_SIGNIN_VIEW").String(); err != nil && s != "" { + // non-boolean value only supports "expensive" at the moment + Service.BlockAnonymousAccessExpensive = s == "expensive" + if !Service.BlockAnonymousAccessExpensive { + log.Fatal("Invalid config option: REQUIRE_SIGNIN_VIEW = %s", s) + } + } + Service.EnableBasicAuth = sec.Key("ENABLE_BASIC_AUTHENTICATION").MustBool(true) Service.EnablePasswordSignInForm = sec.Key("ENABLE_PASSWORD_SIGNIN_FORM").MustBool(true) Service.EnablePasskeyAuth = sec.Key("ENABLE_PASSKEY_AUTHENTICATION").MustBool(true) diff --git a/modules/setting/service_test.go b/modules/setting/service_test.go index 1647bcec16..73736b793a 100644 --- a/modules/setting/service_test.go +++ b/modules/setting/service_test.go @@ -7,16 +7,14 @@ import ( "testing" "code.gitea.io/gitea/modules/structs" + "code.gitea.io/gitea/modules/test" "github.com/gobwas/glob" "github.com/stretchr/testify/assert" ) func TestLoadServices(t *testing.T) { - oldService := Service - defer func() { - Service = oldService - }() + defer test.MockVariableValue(&Service)() cfg, err := NewConfigProviderFromData(` [service] @@ -48,10 +46,7 @@ EMAIL_DOMAIN_BLOCKLIST = d3, *.b } func TestLoadServiceVisibilityModes(t *testing.T) { - oldService := Service - defer func() { - Service = oldService - }() + defer test.MockVariableValue(&Service)() kases := map[string]func(){ ` @@ -130,3 +125,33 @@ ALLOWED_USER_VISIBILITY_MODES = public, limit, privated }) } } + +func TestLoadServiceRequireSignInView(t *testing.T) { + defer test.MockVariableValue(&Service)() + + cfg, err := NewConfigProviderFromData(` +[service] +`) + assert.NoError(t, err) + loadServiceFrom(cfg) + assert.False(t, Service.RequireSignInViewStrict) + assert.False(t, Service.BlockAnonymousAccessExpensive) + + cfg, err = NewConfigProviderFromData(` +[service] +REQUIRE_SIGNIN_VIEW = true +`) + assert.NoError(t, err) + loadServiceFrom(cfg) + assert.True(t, Service.RequireSignInViewStrict) + assert.False(t, Service.BlockAnonymousAccessExpensive) + + cfg, err = NewConfigProviderFromData(` +[service] +REQUIRE_SIGNIN_VIEW = expensive +`) + assert.NoError(t, err) + loadServiceFrom(cfg) + assert.False(t, Service.RequireSignInViewStrict) + assert.True(t, Service.BlockAnonymousAccessExpensive) +} diff --git a/modules/setting/storage_test.go b/modules/setting/storage_test.go index afff85537e..6f5a54c41c 100644 --- a/modules/setting/storage_test.go +++ b/modules/setting/storage_test.go @@ -26,16 +26,16 @@ MINIO_BUCKET = gitea-storage assert.NoError(t, err) assert.NoError(t, loadAttachmentFrom(cfg)) - assert.EqualValues(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-attachment", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "gitea-lfs", LFS.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-lfs", LFS.Storage.MinioConfig.Bucket) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) assert.NoError(t, loadAvatarsFrom(cfg)) - assert.EqualValues(t, "gitea-storage", Avatar.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "avatars/", Avatar.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-storage", Avatar.Storage.MinioConfig.Bucket) + assert.Equal(t, "avatars/", Avatar.Storage.MinioConfig.BasePath) } func Test_getStorageUseOtherNameAsType(t *testing.T) { @@ -51,12 +51,12 @@ MINIO_BUCKET = gitea-storage assert.NoError(t, err) assert.NoError(t, loadAttachmentFrom(cfg)) - assert.EqualValues(t, "gitea-storage", Attachment.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-storage", Attachment.Storage.MinioConfig.Bucket) + assert.Equal(t, "attachments/", Attachment.Storage.MinioConfig.BasePath) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "gitea-storage", LFS.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "lfs/", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea-storage", LFS.Storage.MinioConfig.Bucket) + assert.Equal(t, "lfs/", LFS.Storage.MinioConfig.BasePath) } func Test_getStorageInheritStorageType(t *testing.T) { @@ -69,32 +69,32 @@ STORAGE_TYPE = minio assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "minio", Packages.Storage.Type) - assert.EqualValues(t, "gitea", Packages.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "packages/", Packages.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", Packages.Storage.MinioConfig.Bucket) + assert.Equal(t, "packages/", Packages.Storage.MinioConfig.BasePath) assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "minio", RepoArchive.Storage.Type) - assert.EqualValues(t, "gitea", RepoArchive.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", RepoArchive.Storage.MinioConfig.Bucket) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "minio", Actions.LogStorage.Type) - assert.EqualValues(t, "gitea", Actions.LogStorage.MinioConfig.Bucket) - assert.EqualValues(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) + assert.Equal(t, "gitea", Actions.LogStorage.MinioConfig.Bucket) + assert.Equal(t, "actions_log/", Actions.LogStorage.MinioConfig.BasePath) assert.EqualValues(t, "minio", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "gitea", Actions.ArtifactStorage.MinioConfig.Bucket) - assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) + assert.Equal(t, "gitea", Actions.ArtifactStorage.MinioConfig.Bucket) + assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.MinioConfig.BasePath) assert.NoError(t, loadAvatarsFrom(cfg)) assert.EqualValues(t, "minio", Avatar.Storage.Type) - assert.EqualValues(t, "gitea", Avatar.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "avatars/", Avatar.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", Avatar.Storage.MinioConfig.Bucket) + assert.Equal(t, "avatars/", Avatar.Storage.MinioConfig.BasePath) assert.NoError(t, loadRepoAvatarFrom(cfg)) assert.EqualValues(t, "minio", RepoAvatar.Storage.Type) - assert.EqualValues(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket) - assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath) + assert.Equal(t, "gitea", RepoAvatar.Storage.MinioConfig.Bucket) + assert.Equal(t, "repo-avatars/", RepoAvatar.Storage.MinioConfig.BasePath) } func Test_getStorageInheritStorageTypeAzureBlob(t *testing.T) { @@ -107,32 +107,32 @@ STORAGE_TYPE = azureblob assert.NoError(t, loadPackagesFrom(cfg)) assert.EqualValues(t, "azureblob", Packages.Storage.Type) - assert.EqualValues(t, "gitea", Packages.Storage.AzureBlobConfig.Container) - assert.EqualValues(t, "packages/", Packages.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", Packages.Storage.AzureBlobConfig.Container) + assert.Equal(t, "packages/", Packages.Storage.AzureBlobConfig.BasePath) assert.NoError(t, loadRepoArchiveFrom(cfg)) assert.EqualValues(t, "azureblob", RepoArchive.Storage.Type) - assert.EqualValues(t, "gitea", RepoArchive.Storage.AzureBlobConfig.Container) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", RepoArchive.Storage.AzureBlobConfig.Container) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) assert.NoError(t, loadActionsFrom(cfg)) assert.EqualValues(t, "azureblob", Actions.LogStorage.Type) - assert.EqualValues(t, "gitea", Actions.LogStorage.AzureBlobConfig.Container) - assert.EqualValues(t, "actions_log/", Actions.LogStorage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", Actions.LogStorage.AzureBlobConfig.Container) + assert.Equal(t, "actions_log/", Actions.LogStorage.AzureBlobConfig.BasePath) assert.EqualValues(t, "azureblob", Actions.ArtifactStorage.Type) - assert.EqualValues(t, "gitea", Actions.ArtifactStorage.AzureBlobConfig.Container) - assert.EqualValues(t, "actions_artifacts/", Actions.ArtifactStorage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", Actions.ArtifactStorage.AzureBlobConfig.Container) + assert.Equal(t, "actions_artifacts/", Actions.ArtifactStorage.AzureBlobConfig.BasePath) assert.NoError(t, loadAvatarsFrom(cfg)) assert.EqualValues(t, "azureblob", Avatar.Storage.Type) - assert.EqualValues(t, "gitea", Avatar.Storage.AzureBlobConfig.Container) - assert.EqualValues(t, "avatars/", Avatar.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", Avatar.Storage.AzureBlobConfig.Container) + assert.Equal(t, "avatars/", Avatar.Storage.AzureBlobConfig.BasePath) assert.NoError(t, loadRepoAvatarFrom(cfg)) assert.EqualValues(t, "azureblob", RepoAvatar.Storage.Type) - assert.EqualValues(t, "gitea", RepoAvatar.Storage.AzureBlobConfig.Container) - assert.EqualValues(t, "repo-avatars/", RepoAvatar.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "gitea", RepoAvatar.Storage.AzureBlobConfig.Container) + assert.Equal(t, "repo-avatars/", RepoAvatar.Storage.AzureBlobConfig.BasePath) } type testLocalStoragePathCase struct { @@ -151,7 +151,7 @@ func testLocalStoragePath(t *testing.T, appDataPath, iniStr string, cases []test assert.EqualValues(t, "local", storage.Type) assert.True(t, filepath.IsAbs(storage.Path)) - assert.EqualValues(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path)) + assert.Equal(t, filepath.Clean(c.expectedPath), filepath.Clean(storage.Path)) } } @@ -389,8 +389,8 @@ MINIO_SECRET_ACCESS_KEY = my_secret_key assert.NoError(t, loadRepoArchiveFrom(cfg)) cp := RepoArchive.Storage.ToShadowCopy() - assert.EqualValues(t, "******", cp.MinioConfig.AccessKeyID) - assert.EqualValues(t, "******", cp.MinioConfig.SecretAccessKey) + assert.Equal(t, "******", cp.MinioConfig.AccessKeyID) + assert.Equal(t, "******", cp.MinioConfig.SecretAccessKey) } func Test_getStorageConfiguration24(t *testing.T) { @@ -445,10 +445,10 @@ MINIO_USE_SSL = true `) assert.NoError(t, err) assert.NoError(t, loadRepoArchiveFrom(cfg)) - assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID) - assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey) + assert.Equal(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID) + assert.Equal(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey) assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) } func Test_getStorageConfiguration28(t *testing.T) { @@ -462,10 +462,10 @@ MINIO_BASE_PATH = /prefix `) assert.NoError(t, err) assert.NoError(t, loadRepoArchiveFrom(cfg)) - assert.EqualValues(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID) - assert.EqualValues(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey) + assert.Equal(t, "my_access_key", RepoArchive.Storage.MinioConfig.AccessKeyID) + assert.Equal(t, "my_secret_key", RepoArchive.Storage.MinioConfig.SecretAccessKey) assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL) - assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) cfg, err = NewConfigProviderFromData(` [storage] @@ -476,9 +476,9 @@ MINIO_BASE_PATH = /prefix `) assert.NoError(t, err) assert.NoError(t, loadRepoArchiveFrom(cfg)) - assert.EqualValues(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint) + assert.Equal(t, "127.0.0.1", RepoArchive.Storage.MinioConfig.IamEndpoint) assert.True(t, RepoArchive.Storage.MinioConfig.UseSSL) - assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) + assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.MinioConfig.BasePath) cfg, err = NewConfigProviderFromData(` [storage] @@ -493,10 +493,10 @@ MINIO_BASE_PATH = /lfs `) assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) - assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) + assert.Equal(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) + assert.Equal(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) assert.True(t, LFS.Storage.MinioConfig.UseSSL) - assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "/lfs", LFS.Storage.MinioConfig.BasePath) cfg, err = NewConfigProviderFromData(` [storage] @@ -511,10 +511,10 @@ MINIO_BASE_PATH = /lfs `) assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) - assert.EqualValues(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) + assert.Equal(t, "my_access_key", LFS.Storage.MinioConfig.AccessKeyID) + assert.Equal(t, "my_secret_key", LFS.Storage.MinioConfig.SecretAccessKey) assert.True(t, LFS.Storage.MinioConfig.UseSSL) - assert.EqualValues(t, "/lfs", LFS.Storage.MinioConfig.BasePath) + assert.Equal(t, "/lfs", LFS.Storage.MinioConfig.BasePath) } func Test_getStorageConfiguration29(t *testing.T) { @@ -539,9 +539,9 @@ AZURE_BLOB_ACCOUNT_KEY = my_account_key `) assert.NoError(t, err) assert.NoError(t, loadRepoArchiveFrom(cfg)) - assert.EqualValues(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName) - assert.EqualValues(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey) - assert.EqualValues(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName) + assert.Equal(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey) + assert.Equal(t, "repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) } func Test_getStorageConfiguration31(t *testing.T) { @@ -554,9 +554,9 @@ AZURE_BLOB_BASE_PATH = /prefix `) assert.NoError(t, err) assert.NoError(t, loadRepoArchiveFrom(cfg)) - assert.EqualValues(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName) - assert.EqualValues(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey) - assert.EqualValues(t, "/prefix/repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "my_account_name", RepoArchive.Storage.AzureBlobConfig.AccountName) + assert.Equal(t, "my_account_key", RepoArchive.Storage.AzureBlobConfig.AccountKey) + assert.Equal(t, "/prefix/repo-archive/", RepoArchive.Storage.AzureBlobConfig.BasePath) cfg, err = NewConfigProviderFromData(` [storage] @@ -570,9 +570,9 @@ AZURE_BLOB_BASE_PATH = /lfs `) assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName) - assert.EqualValues(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey) - assert.EqualValues(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName) + assert.Equal(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey) + assert.Equal(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath) cfg, err = NewConfigProviderFromData(` [storage] @@ -586,7 +586,7 @@ AZURE_BLOB_BASE_PATH = /lfs `) assert.NoError(t, err) assert.NoError(t, loadLFSFrom(cfg)) - assert.EqualValues(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName) - assert.EqualValues(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey) - assert.EqualValues(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath) + assert.Equal(t, "my_account_name", LFS.Storage.AzureBlobConfig.AccountName) + assert.Equal(t, "my_account_key", LFS.Storage.AzureBlobConfig.AccountKey) + assert.Equal(t, "/lfs", LFS.Storage.AzureBlobConfig.BasePath) } diff --git a/modules/ssh/ssh.go b/modules/ssh/ssh.go index 7479cfbd95..ff0ad34a0d 100644 --- a/modules/ssh/ssh.go +++ b/modules/ssh/ssh.go @@ -11,7 +11,6 @@ import ( "crypto/x509" "encoding/pem" "errors" - "fmt" "io" "net" "os" @@ -216,7 +215,7 @@ func publicKeyHandler(ctx ssh.Context, key ssh.PublicKey) bool { ctx.Permissions().Permissions = &gossh.Permissions{} setPermExt := func(keyID int64) { ctx.Permissions().Permissions.Extensions = map[string]string{ - giteaPermissionExtensionKeyID: fmt.Sprint(keyID), + giteaPermissionExtensionKeyID: strconv.FormatInt(keyID, 10), } } diff --git a/modules/storage/azureblob_test.go b/modules/storage/azureblob_test.go index 6905db5008..b3791b4916 100644 --- a/modules/storage/azureblob_test.go +++ b/modules/storage/azureblob_test.go @@ -4,9 +4,9 @@ package storage import ( - "bytes" "io" "os" + "strings" "testing" "code.gitea.io/gitea/modules/setting" @@ -33,14 +33,14 @@ func TestAzureBlobStorageIterator(t *testing.T) { func TestAzureBlobStoragePath(t *testing.T) { m := &AzureBlobStorage{cfg: &setting.AzureBlobStorageConfig{BasePath: ""}} - assert.Equal(t, "", m.buildAzureBlobPath("/")) - assert.Equal(t, "", m.buildAzureBlobPath(".")) + assert.Empty(t, m.buildAzureBlobPath("/")) + assert.Empty(t, m.buildAzureBlobPath(".")) assert.Equal(t, "a", m.buildAzureBlobPath("/a")) assert.Equal(t, "a/b", m.buildAzureBlobPath("/a/b/")) m = &AzureBlobStorage{cfg: &setting.AzureBlobStorageConfig{BasePath: "/"}} - assert.Equal(t, "", m.buildAzureBlobPath("/")) - assert.Equal(t, "", m.buildAzureBlobPath(".")) + assert.Empty(t, m.buildAzureBlobPath("/")) + assert.Empty(t, m.buildAzureBlobPath(".")) assert.Equal(t, "a", m.buildAzureBlobPath("/a")) assert.Equal(t, "a/b", m.buildAzureBlobPath("/a/b/")) @@ -76,7 +76,7 @@ func Test_azureBlobObject(t *testing.T) { assert.NoError(t, err) data := "Q2xTckt6Y1hDOWh0" - _, err = s.Save("test.txt", bytes.NewBufferString(data), int64(len(data))) + _, err = s.Save("test.txt", strings.NewReader(data), int64(len(data))) assert.NoError(t, err) obj, err := s.Open("test.txt") assert.NoError(t, err) @@ -86,7 +86,7 @@ func Test_azureBlobObject(t *testing.T) { buf1 := make([]byte, 3) read, err := obj.Read(buf1) assert.NoError(t, err) - assert.EqualValues(t, 3, read) + assert.Equal(t, 3, read) assert.Equal(t, data[2:5], string(buf1)) offset, err = obj.Seek(-5, io.SeekEnd) assert.NoError(t, err) @@ -94,7 +94,7 @@ func Test_azureBlobObject(t *testing.T) { buf2 := make([]byte, 4) read, err = obj.Read(buf2) assert.NoError(t, err) - assert.EqualValues(t, 4, read) + assert.Equal(t, 4, read) assert.Equal(t, data[11:15], string(buf2)) assert.NoError(t, obj.Close()) assert.NoError(t, s.Delete("test.txt")) diff --git a/modules/storage/local_test.go b/modules/storage/local_test.go index 540ced1655..0592fd716b 100644 --- a/modules/storage/local_test.go +++ b/modules/storage/local_test.go @@ -48,7 +48,7 @@ func TestBuildLocalPath(t *testing.T) { t.Run(k.path, func(t *testing.T) { l := LocalStorage{dir: k.localDir} - assert.EqualValues(t, k.expected, l.buildLocalPath(k.path)) + assert.Equal(t, k.expected, l.buildLocalPath(k.path)) }) } } diff --git a/modules/storage/minio_test.go b/modules/storage/minio_test.go index 395da051e8..2726d765dd 100644 --- a/modules/storage/minio_test.go +++ b/modules/storage/minio_test.go @@ -34,19 +34,19 @@ func TestMinioStorageIterator(t *testing.T) { func TestMinioStoragePath(t *testing.T) { m := &MinioStorage{basePath: ""} - assert.Equal(t, "", m.buildMinioPath("/")) - assert.Equal(t, "", m.buildMinioPath(".")) + assert.Empty(t, m.buildMinioPath("/")) + assert.Empty(t, m.buildMinioPath(".")) assert.Equal(t, "a", m.buildMinioPath("/a")) assert.Equal(t, "a/b", m.buildMinioPath("/a/b/")) - assert.Equal(t, "", m.buildMinioDirPrefix("")) + assert.Empty(t, m.buildMinioDirPrefix("")) assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/")) m = &MinioStorage{basePath: "/"} - assert.Equal(t, "", m.buildMinioPath("/")) - assert.Equal(t, "", m.buildMinioPath(".")) + assert.Empty(t, m.buildMinioPath("/")) + assert.Empty(t, m.buildMinioPath(".")) assert.Equal(t, "a", m.buildMinioPath("/a")) assert.Equal(t, "a/b", m.buildMinioPath("/a/b/")) - assert.Equal(t, "", m.buildMinioDirPrefix("")) + assert.Empty(t, m.buildMinioDirPrefix("")) assert.Equal(t, "a/", m.buildMinioDirPrefix("/a/")) m = &MinioStorage{basePath: "/base"} diff --git a/modules/storage/storage_test.go b/modules/storage/storage_test.go index 7edde558f3..08f274e74b 100644 --- a/modules/storage/storage_test.go +++ b/modules/storage/storage_test.go @@ -4,7 +4,7 @@ package storage import ( - "bytes" + "strings" "testing" "code.gitea.io/gitea/modules/setting" @@ -26,7 +26,7 @@ func testStorageIterator(t *testing.T, typStr Type, cfg *setting.Storage) { {"b/x 4.txt", "bx4"}, } for _, f := range testFiles { - _, err = l.Save(f[0], bytes.NewBufferString(f[1]), -1) + _, err = l.Save(f[0], strings.NewReader(f[1]), -1) assert.NoError(t, err) } diff --git a/modules/structs/repo_file.go b/modules/structs/repo_file.go index 82bde96ab6..0cd88b3703 100644 --- a/modules/structs/repo_file.go +++ b/modules/structs/repo_file.go @@ -4,6 +4,8 @@ package structs +import "time" + // FileOptions options for all file APIs type FileOptions struct { // message (optional) for the commit of this file. if not supplied, a default message will be used @@ -121,6 +123,10 @@ type ContentsResponse struct { Path string `json:"path"` SHA string `json:"sha"` LastCommitSHA string `json:"last_commit_sha"` + // swagger:strfmt date-time + LastCommitterDate time.Time `json:"last_committer_date"` + // swagger:strfmt date-time + LastAuthorDate time.Time `json:"last_author_date"` // `type` will be `file`, `dir`, `symlink`, or `submodule` Type string `json:"type"` Size int64 `json:"size"` diff --git a/modules/system/appstate_test.go b/modules/system/appstate_test.go index 911319d00a..b5c057cf88 100644 --- a/modules/system/appstate_test.go +++ b/modules/system/appstate_test.go @@ -38,8 +38,8 @@ func TestAppStateDB(t *testing.T) { item1 := new(testItem1) assert.NoError(t, as.Get(db.DefaultContext, item1)) - assert.Equal(t, "", item1.Val1) - assert.EqualValues(t, 0, item1.Val2) + assert.Empty(t, item1.Val1) + assert.Equal(t, 0, item1.Val2) item1 = new(testItem1) item1.Val1 = "a" @@ -53,7 +53,7 @@ func TestAppStateDB(t *testing.T) { item1 = new(testItem1) assert.NoError(t, as.Get(db.DefaultContext, item1)) assert.Equal(t, "a", item1.Val1) - assert.EqualValues(t, 2, item1.Val2) + assert.Equal(t, 2, item1.Val2) item2 = new(testItem2) assert.NoError(t, as.Get(db.DefaultContext, item2)) diff --git a/modules/templates/helper.go b/modules/templates/helper.go index 3237f8b295..c9d93e089c 100644 --- a/modules/templates/helper.go +++ b/modules/templates/helper.go @@ -9,6 +9,7 @@ import ( "html" "html/template" "net/url" + "strconv" "strings" "time" @@ -73,7 +74,7 @@ func NewFuncMap() template.FuncMap { "TimeEstimateString": timeEstimateString, "LoadTimes": func(startTime time.Time) string { - return fmt.Sprint(time.Since(startTime).Nanoseconds()/1e6) + "ms" + return strconv.FormatInt(time.Since(startTime).Nanoseconds()/1e6, 10) + "ms" }, // ----------------------------------------------------------------- diff --git a/modules/templates/helper_test.go b/modules/templates/helper_test.go index 5d7bc93622..81f8235bd2 100644 --- a/modules/templates/helper_test.go +++ b/modules/templates/helper_test.go @@ -15,7 +15,7 @@ import ( func TestSubjectBodySeparator(t *testing.T) { test := func(input, subject, body string) { - loc := mailSubjectSplit.FindIndex([]byte(input)) + loc := mailSubjectSplit.FindStringIndex(input) if loc == nil { assert.Empty(t, subject, "no subject found, but one expected") assert.Equal(t, body, input) @@ -120,8 +120,8 @@ func TestTemplateEscape(t *testing.T) { func TestQueryBuild(t *testing.T) { t.Run("construct", func(t *testing.T) { - assert.Equal(t, "", string(QueryBuild())) - assert.Equal(t, "", string(QueryBuild("a", nil, "b", false, "c", 0, "d", ""))) + assert.Empty(t, string(QueryBuild())) + assert.Empty(t, string(QueryBuild("a", nil, "b", false, "c", 0, "d", ""))) assert.Equal(t, "a=1&b=true", string(QueryBuild("a", 1, "b", "true"))) // path with query parameters @@ -136,9 +136,9 @@ func TestQueryBuild(t *testing.T) { // only query parameters assert.Equal(t, "&k=1", string(QueryBuild("&", "k", 1))) - assert.Equal(t, "", string(QueryBuild("&", "k", 0))) - assert.Equal(t, "", string(QueryBuild("&k=a", "k", 0))) - assert.Equal(t, "", string(QueryBuild("k=a&", "k", 0))) + assert.Empty(t, string(QueryBuild("&", "k", 0))) + assert.Empty(t, string(QueryBuild("&k=a", "k", 0))) + assert.Empty(t, string(QueryBuild("k=a&", "k", 0))) assert.Equal(t, "a=1&b=2", string(QueryBuild("a=1", "b", 2))) assert.Equal(t, "&a=1&b=2", string(QueryBuild("&a=1", "b", 2))) assert.Equal(t, "a=1&b=2&", string(QueryBuild("a=1&", "b", 2))) diff --git a/modules/templates/htmlrenderer_test.go b/modules/templates/htmlrenderer_test.go index 2a74b74c23..e8b01c30fe 100644 --- a/modules/templates/htmlrenderer_test.go +++ b/modules/templates/htmlrenderer_test.go @@ -65,7 +65,7 @@ func TestHandleError(t *testing.T) { _, err = tmpl.Parse(s) assert.Error(t, err) msg := h(err) - assert.EqualValues(t, strings.TrimSpace(expect), strings.TrimSpace(msg)) + assert.Equal(t, strings.TrimSpace(expect), strings.TrimSpace(msg)) } test("{{", p.handleGenericTemplateError, ` @@ -102,5 +102,5 @@ god knows XXX ---------------------------------------------------------------------- ` actualMsg := p.handleExpectedEndError(errors.New("template: test:1: expected end; found XXX")) - assert.EqualValues(t, strings.TrimSpace(expectedMsg), strings.TrimSpace(actualMsg)) + assert.Equal(t, strings.TrimSpace(expectedMsg), strings.TrimSpace(actualMsg)) } diff --git a/modules/templates/util_avatar.go b/modules/templates/util_avatar.go index 470e24fa61..73fde99f40 100644 --- a/modules/templates/util_avatar.go +++ b/modules/templates/util_avatar.go @@ -5,9 +5,9 @@ package templates import ( "context" - "fmt" "html" "html/template" + "strconv" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/avatars" @@ -28,7 +28,7 @@ func NewAvatarUtils(ctx context.Context) *AvatarUtils { // AvatarHTML creates the HTML for an avatar func AvatarHTML(src string, size int, class, name string) template.HTML { - sizeStr := fmt.Sprintf(`%d`, size) + sizeStr := strconv.Itoa(size) if name == "" { name = "avatar" diff --git a/modules/templates/util_date.go b/modules/templates/util_date.go index 658691ee40..fc3f3f2339 100644 --- a/modules/templates/util_date.go +++ b/modules/templates/util_date.go @@ -99,7 +99,7 @@ func dateTimeFormat(format string, datetime any) template.HTML { attrs = append(attrs, `format="datetime"`, `month="short"`, `day="numeric"`, `hour="numeric"`, `minute="numeric"`, `second="numeric"`, `data-tooltip-content`, `data-tooltip-interactive="true"`) return template.HTML(fmt.Sprintf(`%s`, strings.Join(attrs, " "), datetimeEscaped, textEscaped)) default: - panic(fmt.Sprintf("Unsupported format %s", format)) + panic("Unsupported format " + format) } } diff --git a/modules/templates/util_dict.go b/modules/templates/util_dict.go index 8d6376b522..cc3018a71c 100644 --- a/modules/templates/util_dict.go +++ b/modules/templates/util_dict.go @@ -4,6 +4,7 @@ package templates import ( + "errors" "fmt" "html" "html/template" @@ -33,7 +34,7 @@ func dictMerge(base map[string]any, arg any) bool { // The dot syntax is highly discouraged because it might cause unclear key conflicts. It's always good to use explicit keys. func dict(args ...any) (map[string]any, error) { if len(args)%2 != 0 { - return nil, fmt.Errorf("invalid dict constructor syntax: must have key-value pairs") + return nil, errors.New("invalid dict constructor syntax: must have key-value pairs") } m := make(map[string]any, len(args)/2) for i := 0; i < len(args); i += 2 { diff --git a/modules/templates/util_format.go b/modules/templates/util_format.go index bee6fb7b75..3485e3251e 100644 --- a/modules/templates/util_format.go +++ b/modules/templates/util_format.go @@ -5,6 +5,7 @@ package templates import ( "fmt" + "strconv" "code.gitea.io/gitea/modules/util" ) @@ -24,7 +25,7 @@ func countFmt(data any) string { return "" } if num < 1000 { - return fmt.Sprintf("%d", num) + return strconv.FormatInt(num, 10) } else if num < 1_000_000 { num2 := float32(num) / 1000.0 return fmt.Sprintf("%.1fk", num2) diff --git a/modules/templates/util_format_test.go b/modules/templates/util_format_test.go index 8d466faff0..13a57c24e2 100644 --- a/modules/templates/util_format_test.go +++ b/modules/templates/util_format_test.go @@ -14,5 +14,5 @@ func TestCountFmt(t *testing.T) { assert.Equal(t, "1.3k", countFmt(int64(1317))) assert.Equal(t, "21.3M", countFmt(21317675)) assert.Equal(t, "45.7G", countFmt(45721317675)) - assert.Equal(t, "", countFmt("test")) + assert.Empty(t, countFmt("test")) } diff --git a/modules/templates/util_render.go b/modules/templates/util_render.go index 27316bbfec..ae397d87c9 100644 --- a/modules/templates/util_render.go +++ b/modules/templates/util_render.go @@ -15,8 +15,6 @@ import ( issues_model "code.gitea.io/gitea/models/issues" "code.gitea.io/gitea/modules/emoji" - "code.gitea.io/gitea/modules/fileicon" - "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/htmlutil" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/markup" @@ -181,13 +179,6 @@ func (ut *RenderUtils) RenderLabel(label *issues_model.Label) template.HTML { textColor, itemColor, itemHTML) } -func (ut *RenderUtils) RenderFileIcon(entry *git.TreeEntry) template.HTML { - if setting.UI.FileIconTheme == "material" { - return fileicon.DefaultMaterialIconProvider().FileIcon(ut.ctx, entry) - } - return fileicon.BasicThemeIcon(entry) -} - // RenderEmoji renders html text with emoji post processors func (ut *RenderUtils) RenderEmoji(text string) template.HTML { renderedText, err := markup.PostProcessEmoji(markup.NewRenderContext(ut.ctx), template.HTMLEscapeString(text)) diff --git a/modules/templates/util_render_test.go b/modules/templates/util_render_test.go index 617021e510..26cd1eb348 100644 --- a/modules/templates/util_render_test.go +++ b/modules/templates/util_render_test.go @@ -51,7 +51,7 @@ var testMetas = map[string]string{ "user": "user13", "repo": "repo11", "repoPath": "../../tests/gitea-repositories-meta/user13/repo11.git/", - "markdownLineBreakStyle": "comment", + "markdownNewLineHardBreak": "true", "markupAllowShortIssuePattern": "true", } @@ -123,16 +123,16 @@ func TestRenderCommitBody(t *testing.T) {  [[local image|image.jpg]] [[remote link|https://example.com/image.jpg]] -88fc37a3c0...12fc37a3c0 (hash) +88fc37a3c0...12fc37a3c0 (hash) com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb...12fc37a3c0a4dda553bdcfc80c178a58247f42fb pare -88fc37a3c0 +88fc37a3c0 com 88fc37a3c0a4dda553bdcfc80c178a58247f42fb mit 👍 mail@domain.com @mention-user test #123 space` - assert.EqualValues(t, expected, string(newTestRenderUtils(t).RenderCommitBody(testInput(), testMetas))) + assert.Equal(t, expected, string(newTestRenderUtils(t).RenderCommitBody(testInput(), testMetas))) } func TestRenderCommitMessage(t *testing.T) { @@ -169,7 +169,7 @@ mail@domain.com space ` expected = strings.ReplaceAll(expected, "", " ") - assert.EqualValues(t, expected, string(newTestRenderUtils(t).RenderIssueTitle(testInput(), testMetas))) + assert.Equal(t, expected, string(newTestRenderUtils(t).RenderIssueTitle(testInput(), testMetas))) } func TestRenderMarkdownToHtml(t *testing.T) { @@ -214,5 +214,5 @@ func TestRenderLabels(t *testing.T) { func TestUserMention(t *testing.T) { markup.RenderBehaviorForTesting.DisableAdditionalAttributes = true rendered := newTestRenderUtils(t).MarkdownToHtml("@no-such-user @mention-user @mention-user") - assert.EqualValues(t, `@no-such-user @mention-user @mention-user`, strings.TrimSpace(string(rendered))) + assert.Equal(t, `@no-such-user @mention-user @mention-user`, strings.TrimSpace(string(rendered))) } diff --git a/modules/templates/util_test.go b/modules/templates/util_test.go index febaf7fa88..a6448a6ff2 100644 --- a/modules/templates/util_test.go +++ b/modules/templates/util_test.go @@ -28,7 +28,7 @@ func TestDict(t *testing.T) { for _, c := range cases { got, err := dict(c.args...) if assert.NoError(t, err) { - assert.EqualValues(t, c.want, got) + assert.Equal(t, c.want, got) } } diff --git a/modules/templates/vars/vars.go b/modules/templates/vars/vars.go index cc9d0e976f..500078d4b8 100644 --- a/modules/templates/vars/vars.go +++ b/modules/templates/vars/vars.go @@ -16,7 +16,7 @@ type ErrWrongSyntax struct { } func (err ErrWrongSyntax) Error() string { - return fmt.Sprintf("wrong syntax found in %s", err.Template) + return "wrong syntax found in " + err.Template } // ErrVarMissing represents an error that no matched variable diff --git a/modules/templates/vars/vars_test.go b/modules/templates/vars/vars_test.go index 8f421d9e4b..9b48167237 100644 --- a/modules/templates/vars/vars_test.go +++ b/modules/templates/vars/vars_test.go @@ -60,7 +60,7 @@ func TestExpandVars(t *testing.T) { for _, kase := range kases { t.Run(kase.tmpl, func(t *testing.T) { res, err := Expand(kase.tmpl, kase.data) - assert.EqualValues(t, kase.out, res) + assert.Equal(t, kase.out, res) if kase.error { assert.Error(t, err) } else { diff --git a/modules/test/logchecker.go b/modules/test/logchecker.go index 7bf234f560..829f735c7c 100644 --- a/modules/test/logchecker.go +++ b/modules/test/logchecker.go @@ -5,7 +5,7 @@ package test import ( "context" - "fmt" + "strconv" "strings" "sync" "sync/atomic" @@ -58,7 +58,7 @@ var checkerIndex int64 func NewLogChecker(namePrefix string) (logChecker *LogChecker, cancel func()) { logger := log.GetManager().GetLogger(namePrefix) newCheckerIndex := atomic.AddInt64(&checkerIndex, 1) - writerName := namePrefix + "-" + fmt.Sprint(newCheckerIndex) + writerName := namePrefix + "-" + strconv.FormatInt(newCheckerIndex, 10) lc := &LogChecker{} lc.EventWriterBaseImpl = log.NewEventWriterBase(writerName, "test-log-checker", log.WriterMode{}) diff --git a/modules/test/utils.go b/modules/test/utils.go index ec4c976388..3051d3d286 100644 --- a/modules/test/utils.go +++ b/modules/test/utils.go @@ -4,7 +4,6 @@ package test import ( - "fmt" "net/http" "net/http/httptest" "os" @@ -57,7 +56,7 @@ func SetupGiteaRoot() string { giteaRoot = filepath.Dir(filepath.Dir(filepath.Dir(filename))) fixturesDir := filepath.Join(giteaRoot, "models", "fixtures") if exist, _ := util.IsDir(fixturesDir); !exist { - panic(fmt.Sprintf("fixtures directory not found: %s", fixturesDir)) + panic("fixtures directory not found: " + fixturesDir) } _ = os.Setenv("GITEA_ROOT", giteaRoot) return giteaRoot diff --git a/modules/translation/translation_test.go b/modules/translation/translation_test.go index 464aa32661..87df9eb825 100644 --- a/modules/translation/translation_test.go +++ b/modules/translation/translation_test.go @@ -20,13 +20,13 @@ func TestPrettyNumber(t *testing.T) { allLangMap["id-ID"] = &LangType{Lang: "id-ID", Name: "Bahasa Indonesia"} l := NewLocale("id-ID") - assert.EqualValues(t, "1.000.000", l.PrettyNumber(1000000)) - assert.EqualValues(t, "1.000.000,1", l.PrettyNumber(1000000.1)) - assert.EqualValues(t, "1.000.000", l.PrettyNumber("1000000")) - assert.EqualValues(t, "1.000.000", l.PrettyNumber("1000000.0")) - assert.EqualValues(t, "1.000.000,1", l.PrettyNumber("1000000.1")) + assert.Equal(t, "1.000.000", l.PrettyNumber(1000000)) + assert.Equal(t, "1.000.000,1", l.PrettyNumber(1000000.1)) + assert.Equal(t, "1.000.000", l.PrettyNumber("1000000")) + assert.Equal(t, "1.000.000", l.PrettyNumber("1000000.0")) + assert.Equal(t, "1.000.000,1", l.PrettyNumber("1000000.1")) l = NewLocale("nosuch") - assert.EqualValues(t, "1,000,000", l.PrettyNumber(1000000)) - assert.EqualValues(t, "1,000,000.1", l.PrettyNumber(1000000.1)) + assert.Equal(t, "1,000,000", l.PrettyNumber(1000000)) + assert.Equal(t, "1,000,000.1", l.PrettyNumber(1000000.1)) } diff --git a/modules/updatechecker/update_checker.go b/modules/updatechecker/update_checker.go index 3c1e05d060..f0686c0f78 100644 --- a/modules/updatechecker/update_checker.go +++ b/modules/updatechecker/update_checker.go @@ -34,7 +34,7 @@ func GiteaUpdateChecker(httpEndpoint string) error { }, } - req, err := http.NewRequest("GET", httpEndpoint, nil) + req, err := http.NewRequest(http.MethodGet, httpEndpoint, nil) if err != nil { return err } diff --git a/modules/util/paginate_test.go b/modules/util/paginate_test.go index 6e69dd19cc..3dc5095071 100644 --- a/modules/util/paginate_test.go +++ b/modules/util/paginate_test.go @@ -13,23 +13,23 @@ func TestPaginateSlice(t *testing.T) { stringSlice := []string{"a", "b", "c", "d", "e"} result, ok := PaginateSlice(stringSlice, 1, 2).([]string) assert.True(t, ok) - assert.EqualValues(t, []string{"a", "b"}, result) + assert.Equal(t, []string{"a", "b"}, result) result, ok = PaginateSlice(stringSlice, 100, 2).([]string) assert.True(t, ok) - assert.EqualValues(t, []string{}, result) + assert.Equal(t, []string{}, result) result, ok = PaginateSlice(stringSlice, 3, 2).([]string) assert.True(t, ok) - assert.EqualValues(t, []string{"e"}, result) + assert.Equal(t, []string{"e"}, result) result, ok = PaginateSlice(stringSlice, 1, 0).([]string) assert.True(t, ok) - assert.EqualValues(t, []string{"a", "b", "c", "d", "e"}, result) + assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result) result, ok = PaginateSlice(stringSlice, 1, -1).([]string) assert.True(t, ok) - assert.EqualValues(t, []string{"a", "b", "c", "d", "e"}, result) + assert.Equal(t, []string{"a", "b", "c", "d", "e"}, result) type Test struct { Val int @@ -38,9 +38,9 @@ func TestPaginateSlice(t *testing.T) { testVar := []*Test{{Val: 2}, {Val: 3}, {Val: 4}} testVar, ok = PaginateSlice(testVar, 1, 50).([]*Test) assert.True(t, ok) - assert.EqualValues(t, []*Test{{Val: 2}, {Val: 3}, {Val: 4}}, testVar) + assert.Equal(t, []*Test{{Val: 2}, {Val: 3}, {Val: 4}}, testVar) testVar, ok = PaginateSlice(testVar, 2, 2).([]*Test) assert.True(t, ok) - assert.EqualValues(t, []*Test{{Val: 4}}, testVar) + assert.Equal(t, []*Test{{Val: 4}}, testVar) } diff --git a/modules/util/sec_to_time_test.go b/modules/util/sec_to_time_test.go index b67926bbcf..84e767c6e0 100644 --- a/modules/util/sec_to_time_test.go +++ b/modules/util/sec_to_time_test.go @@ -24,5 +24,5 @@ func TestSecToHours(t *testing.T) { assert.Equal(t, "672 hours", SecToHours(4*7*day)) assert.Equal(t, "1 second", SecToHours(1)) assert.Equal(t, "2 seconds", SecToHours(2)) - assert.Equal(t, "", SecToHours(nil)) // old behavior, empty means no output + assert.Empty(t, SecToHours(nil)) // old behavior, empty means no output } diff --git a/modules/util/truncate_test.go b/modules/util/truncate_test.go index 8789c824f5..9f4ad7dc20 100644 --- a/modules/util/truncate_test.go +++ b/modules/util/truncate_test.go @@ -5,6 +5,7 @@ package util import ( "fmt" + "strconv" "strings" "testing" @@ -100,7 +101,7 @@ func TestEllipsisString(t *testing.T) { {limit: 7, left: "\xef\x03\xfe\xef\x03\xfe", right: ""}, } for _, c := range invalidCases { - t.Run(fmt.Sprintf("%d", c.limit), func(t *testing.T) { + t.Run(strconv.Itoa(c.limit), func(t *testing.T) { left, right := EllipsisDisplayStringX("\xef\x03\xfe\xef\x03\xfe", c.limit) assert.Equal(t, c.left, left, "left") assert.Equal(t, c.right, right, "right") @@ -115,15 +116,15 @@ func TestEllipsisString(t *testing.T) { } func TestTruncateRunes(t *testing.T) { - assert.Equal(t, "", TruncateRunes("", 0)) - assert.Equal(t, "", TruncateRunes("", 1)) + assert.Empty(t, TruncateRunes("", 0)) + assert.Empty(t, TruncateRunes("", 1)) - assert.Equal(t, "", TruncateRunes("ab", 0)) + assert.Empty(t, TruncateRunes("ab", 0)) assert.Equal(t, "a", TruncateRunes("ab", 1)) assert.Equal(t, "ab", TruncateRunes("ab", 2)) assert.Equal(t, "ab", TruncateRunes("ab", 3)) - assert.Equal(t, "", TruncateRunes("测试", 0)) + assert.Empty(t, TruncateRunes("测试", 0)) assert.Equal(t, "测", TruncateRunes("测试", 1)) assert.Equal(t, "测试", TruncateRunes("测试", 2)) assert.Equal(t, "测试", TruncateRunes("测试", 3)) diff --git a/modules/util/util.go b/modules/util/util.go index 72fcddbe13..dd8e073888 100644 --- a/modules/util/util.go +++ b/modules/util/util.go @@ -219,6 +219,13 @@ func IfZero[T comparable](v, def T) T { return v } +func IfEmpty[T any](v, def []T) []T { + if len(v) == 0 { + return def + } + return v +} + // OptionalArg helps the "optional argument" in Golang: // // func foo(optArg ...int) { return OptionalArg(optArg) } diff --git a/modules/validation/binding_test.go b/modules/validation/binding_test.go index 28d0f57b5c..0cd328f312 100644 --- a/modules/validation/binding_test.go +++ b/modules/validation/binding_test.go @@ -47,7 +47,7 @@ func performValidationTest(t *testing.T, testCase validationTestCase) { assert.Equal(t, testCase.expectedErrors, actual) }) - req, err := http.NewRequest("POST", testRoute, nil) + req, err := http.NewRequest(http.MethodPost, testRoute, nil) if err != nil { panic(err) } diff --git a/modules/web/routemock_test.go b/modules/web/routemock_test.go index 89cfaacdd1..a0949bf622 100644 --- a/modules/web/routemock_test.go +++ b/modules/web/routemock_test.go @@ -30,13 +30,13 @@ func TestRouteMock(t *testing.T) { // normal request recorder := httptest.NewRecorder() - req, err := http.NewRequest("GET", "http://localhost:8000/foo", nil) + req, err := http.NewRequest(http.MethodGet, "http://localhost:8000/foo", nil) assert.NoError(t, err) r.ServeHTTP(recorder, req) assert.Len(t, recorder.Header(), 3) - assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) - assert.EqualValues(t, "m2", recorder.Header().Get("X-Test-Middleware2")) - assert.EqualValues(t, "h", recorder.Header().Get("X-Test-Handler")) + assert.Equal(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.Equal(t, "m2", recorder.Header().Get("X-Test-Middleware2")) + assert.Equal(t, "h", recorder.Header().Get("X-Test-Handler")) RouteMockReset() // mock at "mock-point" @@ -45,12 +45,12 @@ func TestRouteMock(t *testing.T) { resp.WriteHeader(http.StatusOK) }) recorder = httptest.NewRecorder() - req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil) + req, err = http.NewRequest(http.MethodGet, "http://localhost:8000/foo", nil) assert.NoError(t, err) r.ServeHTTP(recorder, req) assert.Len(t, recorder.Header(), 2) - assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) - assert.EqualValues(t, "a", recorder.Header().Get("X-Test-MockPoint")) + assert.Equal(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.Equal(t, "a", recorder.Header().Get("X-Test-MockPoint")) RouteMockReset() // mock at MockAfterMiddlewares @@ -59,12 +59,12 @@ func TestRouteMock(t *testing.T) { resp.WriteHeader(http.StatusOK) }) recorder = httptest.NewRecorder() - req, err = http.NewRequest("GET", "http://localhost:8000/foo", nil) + req, err = http.NewRequest(http.MethodGet, "http://localhost:8000/foo", nil) assert.NoError(t, err) r.ServeHTTP(recorder, req) assert.Len(t, recorder.Header(), 3) - assert.EqualValues(t, "m1", recorder.Header().Get("X-Test-Middleware1")) - assert.EqualValues(t, "m2", recorder.Header().Get("X-Test-Middleware2")) - assert.EqualValues(t, "b", recorder.Header().Get("X-Test-MockPoint")) + assert.Equal(t, "m1", recorder.Header().Get("X-Test-Middleware1")) + assert.Equal(t, "m2", recorder.Header().Get("X-Test-Middleware2")) + assert.Equal(t, "b", recorder.Header().Get("X-Test-MockPoint")) RouteMockReset() } diff --git a/modules/web/router_path.go b/modules/web/router_path.go index b59948581a..baf1b522af 100644 --- a/modules/web/router_path.go +++ b/modules/web/router_path.go @@ -4,7 +4,6 @@ package web import ( - "fmt" "net/http" "regexp" "strings" @@ -103,7 +102,7 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher for _, method := range strings.Split(methods, ",") { method = strings.TrimSpace(method) if !isValidMethod(method) { - panic(fmt.Sprintf("invalid HTTP method: %s", method)) + panic("invalid HTTP method: " + method) } p.methods.Add(method) } @@ -117,7 +116,7 @@ func newRouterPathMatcher(methods, pattern string, h ...any) *routerPathMatcher } end := strings.IndexByte(pattern[lastEnd+start:], '>') if end == -1 { - panic(fmt.Sprintf("invalid pattern: %s", pattern)) + panic("invalid pattern: " + pattern) } re = append(re, pattern[lastEnd:lastEnd+start]...) partName, partExp, _ := strings.Cut(pattern[lastEnd+start+1:lastEnd+start+end], ":") diff --git a/modules/web/router_test.go b/modules/web/router_test.go index 582980a27a..21619012ea 100644 --- a/modules/web/router_test.go +++ b/modules/web/router_test.go @@ -51,7 +51,7 @@ func TestPathProcessor(t *testing.T) { } func TestRouter(t *testing.T) { - buff := bytes.NewBufferString("") + buff := &bytes.Buffer{} recorder := httptest.NewRecorder() recorder.Body = buff @@ -121,7 +121,7 @@ func TestRouter(t *testing.T) { req, err := http.NewRequest(methodPathFields[0], methodPathFields[1], nil) assert.NoError(t, err) r.ServeHTTP(recorder, req) - assert.EqualValues(t, expected, res) + assert.Equal(t, expected, res) }) } @@ -224,7 +224,7 @@ func TestRouteNormalizePath(t *testing.T) { actualPaths.Path = req.URL.Path }) - req, err := http.NewRequest("GET", reqPath, nil) + req, err := http.NewRequest(http.MethodGet, reqPath, nil) assert.NoError(t, err) r.ServeHTTP(recorder, req) assert.Equal(t, expectedPaths, actualPaths, "req path = %q", reqPath) diff --git a/options/locale/locale_cs-CZ.ini b/options/locale/locale_cs-CZ.ini index 57d7e8e076..af366868b1 100644 --- a/options/locale/locale_cs-CZ.ini +++ b/options/locale/locale_cs-CZ.ini @@ -718,8 +718,6 @@ public_profile=Veřejný profil biography_placeholder=Řekněte nám něco o sobě! (Můžete použít Markdown) location_placeholder=Sdílejte svou přibližnou polohu s ostatními profile_desc=Nastavte, jak bude váš profil zobrazen ostatním uživatelům. Vaše hlavní e-mailová adresa bude použita pro oznámení, obnovení hesla a operace Git. -password_username_disabled=Nemáte oprávnění měnit jejich uživatelské jméno. Pro více informací kontaktujte svého administrátora. -password_full_name_disabled=Nemáte oprávnění měnit jejich celé jméno. Pro více informací kontaktujte správce webu. full_name=Celé jméno website=Web location=Místo @@ -1529,7 +1527,6 @@ issues.filter_project=Projekt issues.filter_project_all=Všechny projekty issues.filter_project_none=Žádný projekt issues.filter_assignee=Zpracovatel -issues.filter_assginee_no_assignee=Bez zpracovatele issues.filter_poster=Autor issues.filter_user_placeholder=Hledat uživatele issues.filter_user_no_select=Všichni uživatelé @@ -2157,7 +2154,6 @@ settings.advanced_settings=Pokročilá nastavení settings.wiki_desc=Povolit Wiki repozitáře settings.use_internal_wiki=Používat vestavěnou Wiki settings.default_wiki_branch_name=Výchozí název větve Wiki -settings.default_permission_everyone_access=Výchozí přístupová práva pro všechny přihlášené uživatele: settings.failed_to_change_default_wiki_branch=Změna výchozí větve wiki se nezdařila. settings.use_external_wiki=Používat externí Wiki settings.external_wiki_url=URL externí Wiki diff --git a/options/locale/locale_de-DE.ini b/options/locale/locale_de-DE.ini index 0b0544b89c..50ade526ff 100644 --- a/options/locale/locale_de-DE.ini +++ b/options/locale/locale_de-DE.ini @@ -724,8 +724,6 @@ public_profile=Öffentliches Profil biography_placeholder=Erzähle uns ein wenig über Dich selbst! (Du kannst Markdown verwenden) location_placeholder=Teile Deinen ungefähren Standort mit anderen profile_desc=Lege fest, wie dein Profil anderen Benutzern angezeigt wird. Deine primäre E-Mail-Adresse wird für Benachrichtigungen, Passwort-Wiederherstellung und webbasierte Git-Operationen verwendet. -password_username_disabled=Du bist nicht berechtigt, den Benutzernamen zu ändern. Bitte kontaktiere Deinen Seitenadministrator für weitere Details. -password_full_name_disabled=Du bist nicht berechtigt, den vollständigen Namen zu ändern. Bitte kontaktiere Deinen Seitenadministrator für weitere Details. full_name=Vollständiger Name website=Webseite location=Standort @@ -1530,7 +1528,6 @@ issues.filter_project=Projekt issues.filter_project_all=Alle Projekte issues.filter_project_none=Kein Projekt issues.filter_assignee=Zuständig -issues.filter_assginee_no_assignee=Niemand zuständig issues.filter_poster=Autor issues.filter_user_placeholder=Benutzer suchen issues.filter_user_no_select=Alle Benutzer diff --git a/options/locale/locale_el-GR.ini b/options/locale/locale_el-GR.ini index f430c0506c..960e3b1581 100644 --- a/options/locale/locale_el-GR.ini +++ b/options/locale/locale_el-GR.ini @@ -1377,7 +1377,6 @@ issues.filter_project=Έργο issues.filter_project_all=Όλα τα έργα issues.filter_project_none=Χωρίς έργα issues.filter_assignee=Αποδέκτης -issues.filter_assginee_no_assignee=Κανένας Αποδέκτης issues.filter_poster=Συγγραφέας issues.filter_type=Τύπος issues.filter_type.all_issues=Όλα τα ζητήματα diff --git a/options/locale/locale_en-US.ini b/options/locale/locale_en-US.ini index 8ce469359c..96c99615f5 100644 --- a/options/locale/locale_en-US.ini +++ b/options/locale/locale_en-US.ini @@ -730,8 +730,8 @@ public_profile = Public Profile biography_placeholder = Tell us a little bit about yourself! (You can use Markdown) location_placeholder = Share your approximate location with others profile_desc = Control how your profile is show to other users. Your primary email address will be used for notifications, password recovery and web-based Git operations. -password_username_disabled = You are not allowed to change their username. Please contact your site administrator for more details. -password_full_name_disabled = You are not allowed to change their full name. Please contact your site administrator for more details. +password_username_disabled = You are not allowed to change your username. Please contact your site administrator for more details. +password_full_name_disabled = You are not allowed to change your full name. Please contact your site administrator for more details. full_name = Full Name website = Website location = Location @@ -1551,7 +1551,7 @@ issues.filter_project = Project issues.filter_project_all = All projects issues.filter_project_none = No project issues.filter_assignee = Assignee -issues.filter_assginee_no_assignee = Assigned to nobody +issues.filter_assignee_no_assignee = Assigned to nobody issues.filter_assignee_any_assignee = Assigned to anybody issues.filter_poster = Author issues.filter_user_placeholder = Search users @@ -2733,6 +2733,7 @@ branch.restore_success = Branch "%s" has been restored. branch.restore_failed = Failed to restore branch "%s". branch.protected_deletion_failed = Branch "%s" is protected. It cannot be deleted. branch.default_deletion_failed = Branch "%s" is the default branch. It cannot be deleted. +branch.default_branch_not_exist = Default branch "%s" does not exist. branch.restore = Restore Branch "%s" branch.download = Download Branch "%s" branch.rename = Rename Branch "%s" diff --git a/options/locale/locale_es-ES.ini b/options/locale/locale_es-ES.ini index debf9a6f5d..280c735c79 100644 --- a/options/locale/locale_es-ES.ini +++ b/options/locale/locale_es-ES.ini @@ -1367,7 +1367,6 @@ issues.filter_project=Proyecto issues.filter_project_all=Todos los proyectos issues.filter_project_none=Ningún proyecto issues.filter_assignee=Asignada a -issues.filter_assginee_no_assignee=Sin asignado issues.filter_poster=Autor issues.filter_type=Tipo issues.filter_type.all_issues=Todas las incidencias diff --git a/options/locale/locale_fa-IR.ini b/options/locale/locale_fa-IR.ini index 5c96cea8f6..c7bef6e6dc 100644 --- a/options/locale/locale_fa-IR.ini +++ b/options/locale/locale_fa-IR.ini @@ -1059,7 +1059,6 @@ issues.filter_label_no_select=تمامی برچسبها issues.filter_milestone=نقطه عطف issues.filter_project_none=هیچ پروژه ثبت نشده issues.filter_assignee=مسئول رسیدگی -issues.filter_assginee_no_assignee=بدون مسئول رسیدگی issues.filter_type=نوع issues.filter_type.all_issues=همه مسائل issues.filter_type.assigned_to_you=به شما محول شده diff --git a/options/locale/locale_fr-FR.ini b/options/locale/locale_fr-FR.ini index c9b3345382..db70eaf66a 100644 --- a/options/locale/locale_fr-FR.ini +++ b/options/locale/locale_fr-FR.ini @@ -457,6 +457,7 @@ 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.general=Une erreur s’est produite lors du traitement de la demande d’autorisation : %s. Si l’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. oauth_callback_unable_auto_reg=L’inscription automatique est activée, mais le fournisseur OAuth2 %[1]s a signalé des champs manquants : %[2]s, impossible de créer un compte automatiquement, veuillez créer ou lier un compte, ou bien contacter l’administrateur du site. @@ -729,8 +730,6 @@ public_profile=Profil public biography_placeholder=Parlez-nous un peu de vous ! (Vous pouvez utiliser Markdown) location_placeholder=Partagez votre position approximative avec d'autres personnes profile_desc=Contrôlez comment votre profil est affiché aux autres utilisateurs. Votre adresse courriel principale sera utilisée pour les notifications, la récupération de mot de passe et les opérations Git basées sur le Web. -password_username_disabled=Vous n’êtes pas autorisé à modifier leur nom d’utilisateur. Veuillez contacter l’administrateur de votre site pour plus de détails. -password_full_name_disabled=Vous n’êtes pas autorisé à modifier leur nom complet. Veuillez contacter l’administrateur du site pour plus de détails. full_name=Nom complet website=Site Web location=Localisation @@ -1545,6 +1544,8 @@ issues.filter_project=Projet issues.filter_project_all=Tous les projets issues.filter_project_none=Aucun projet issues.filter_assignee=Assigné +issues.filter_assignee_no_assignee=Non-assigné +issues.filter_assignee_any_assignee=Assigné issues.filter_poster=Auteur issues.filter_user_placeholder=Rechercher des utilisateurs issues.filter_user_no_select=Tous les utilisateurs @@ -2175,7 +2176,6 @@ settings.advanced_settings=Paramètres avancés settings.wiki_desc=Activer le wiki du dépôt settings.use_internal_wiki=Utiliser le wiki interne settings.default_wiki_branch_name=Nom de la branche du Wiki par défaut -settings.default_permission_everyone_access=Autorisation d’accès par défaut pour tous les utilisateurs connectés : settings.failed_to_change_default_wiki_branch=Impossible de modifier la branche du wiki par défaut. settings.use_external_wiki=Utiliser un wiki externe settings.external_wiki_url=URL Wiki externe @@ -2720,6 +2720,7 @@ branch.restore_success=La branche "%s" a été restaurée. branch.restore_failed=Impossible de restaurer la branche "%s". branch.protected_deletion_failed=La branche "%s" est protégé. Elle ne peut pas être supprimée. branch.default_deletion_failed=La branche "%s" est la branche par défaut. Elle ne peut pas être supprimée. +branch.default_branch_not_exist=La branche par défaut « %s » n‘existe pas. branch.restore=`Restaurer la branche "%s"` branch.download=`Télécharger la branche "%s"` branch.rename=`Renommer la branche "%s"` diff --git a/options/locale/locale_ga-IE.ini b/options/locale/locale_ga-IE.ini index 35ca330d6d..f2e5de942a 100644 --- a/options/locale/locale_ga-IE.ini +++ b/options/locale/locale_ga-IE.ini @@ -730,8 +730,6 @@ public_profile=Próifíl Phoiblí biography_placeholder=Inis dúinn beagán fút féin! (Is féidir leat Markdown a úsáid) location_placeholder=Comhroinn do shuíomh thart le daoine eile profile_desc=Rialú conas a thaispeánfar do phróifíl d'úsáideoirí eile. Úsáidfear do phríomhsheoladh ríomhphoist le haghaidh fógraí, aisghabháil pasfhocail agus oibríochtaí Git gréasán-bhunaithe. -password_username_disabled=Níl cead agat a n-ainm úsáideora a athrú. Déan teagmháil le do riarthóir suímh le haghaidh tuilleadh sonraí. -password_full_name_disabled=Níl cead agat a n-ainm iomlán a athrú. Déan teagmháil le do riarthóir suímh le haghaidh tuilleadh sonraí. full_name=Ainm Iomlán website=Láithreán Gréasáin location=Suíomh @@ -926,6 +924,9 @@ permission_not_set=Níl leagtha permission_no_access=Gan rochtain permission_read=Léigh permission_write=Léigh agus Scríobh +permission_anonymous_read=Léamh gan Ainm +permission_everyone_read=Léigh gach duine +permission_everyone_write=Scríobh gach duine access_token_desc=Ní chuireann ceadchomharthaí roghnaithe ach teorainn leis an údarú do na bealaí API comhfhreagracha. Léigh doiciméadúchán chun tuilleadh eolais a fháil. at_least_one_permission=Ní mór duit cead amháin ar a laghad a roghnú chun comhartha a chruthú permissions_list=Ceadanna: @@ -1138,6 +1139,7 @@ transfer.no_permission_to_reject=Níl cead agat an aistriú seo a dhiúltú. desc.private=Príobháideach desc.public=Poiblí +desc.public_access=Rochtain Phoiblí desc.template=Teimpléad desc.internal=Inmheánach desc.archived=Cartlannaithe @@ -1546,7 +1548,6 @@ issues.filter_project=Tionscadal issues.filter_project_all=Gach tionscadal issues.filter_project_none=Gan aon tionscadal issues.filter_assignee=Sannaitheoir -issues.filter_assginee_no_assignee=Sannta do dhuine ar bith issues.filter_assignee_any_assignee=Sannta do dhuine ar bith issues.filter_poster=Údar issues.filter_user_placeholder=Cuardaigh úsáideoirí @@ -2132,6 +2133,12 @@ contributors.contribution_type.deletions=Scriosadh settings=Socruithe settings.desc=Is é socruithe an áit ar féidir leat na socruithe don stóras a bhainistiú settings.options=Stóras +settings.public_access=Rochtain Phoiblí +settings.public_access_desc=Cumraigh ceadanna rochtana an chuairteora phoiblí chun réamhshocruithe an stóras seo a shárú. +settings.public_access.docs.not_set=Gan Socrú: níl cead rochtana poiblí breise ar bith. Leanann cead an chuairteora infheictheacht an stór agus ceadanna na mball. +settings.public_access.docs.anonymous_read=Léamh gan Ainm: is féidir le húsáideoirí nach bhfuil logáilte isteach rochtain a fháil ar an aonad le cead léite. +settings.public_access.docs.everyone_read=Léamh ag Gach Duine: is féidir le gach úsáideoir logáilte isteach rochtain a fháil ar an aonad le cead léite. Ciallaíonn cead léite na n-aonad eisiúna/iarrataí tarraingthe freisin gur féidir le húsáideoirí saincheisteanna nua/iarratais tarraingthe a chruthú. +settings.public_access.docs.everyone_write=Scríobh Gach Duine: tá cead scríofa ag gach úsáideoir logáilte isteach don aonad. Ní thacaíonn ach aonad Vicí leis an gcead seo. settings.collaboration=Comhoibritheoirí settings.collaboration.admin=Riarthóir settings.collaboration.write=Scríobh @@ -2178,7 +2185,6 @@ settings.advanced_settings=Ardsocruithe settings.wiki_desc=Cumasaigh Stór Vicí settings.use_internal_wiki=Úsáid Vicí Insuite settings.default_wiki_branch_name=Ainm Brainse Réamhshocraithe Vicí -settings.default_permission_everyone_access=Cead rochtana réamhshocraithe do gach úsáideoir sínithe isteach: settings.failed_to_change_default_wiki_branch=Theip ar an brainse réamhshocraithe vicí a athrú. settings.use_external_wiki=Úsáid Vicí Seachtrach settings.external_wiki_url=URL Vicí Seachtrach diff --git a/options/locale/locale_it-IT.ini b/options/locale/locale_it-IT.ini index 3ce5a6770f..810f1040f5 100644 --- a/options/locale/locale_it-IT.ini +++ b/options/locale/locale_it-IT.ini @@ -1143,7 +1143,6 @@ issues.filter_milestone=Traguardo issues.filter_project=Progetto issues.filter_project_none=Nessun progetto issues.filter_assignee=Assegnatario -issues.filter_assginee_no_assignee=Nessun assegnatario issues.filter_poster=Autore issues.filter_type=Tipo issues.filter_type.all_issues=Tutti i problemi diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini index 9c25c568fa..4fe3a2ef60 100644 --- a/options/locale/locale_ja-JP.ini +++ b/options/locale/locale_ja-JP.ini @@ -730,8 +730,6 @@ public_profile=公開プロフィール biography_placeholder=自己紹介してください!(Markdownを使うことができます) location_placeholder=おおよその場所を他の人と共有 profile_desc=あなたのプロフィールが他のユーザーにどのように表示されるかを制御します。あなたのプライマリメールアドレスは、通知、パスワードの回復、WebベースのGit操作に使用されます。 -password_username_disabled=ユーザー名の変更は許可されていません。詳細はサイト管理者にお問い合わせください。 -password_full_name_disabled=フルネームの変更は許可されていません。詳細はサイト管理者にお問い合わせください。 full_name=フルネーム website=Webサイト location=場所 @@ -1546,7 +1544,6 @@ issues.filter_project=プロジェクト issues.filter_project_all=すべてのプロジェクト issues.filter_project_none=プロジェクトなし issues.filter_assignee=担当者 -issues.filter_assginee_no_assignee=担当者なし issues.filter_assignee_any_assignee=担当者あり issues.filter_poster=作成者 issues.filter_user_placeholder=ユーザーを検索 @@ -2178,7 +2175,6 @@ settings.advanced_settings=拡張設定 settings.wiki_desc=Wikiを有効にする settings.use_internal_wiki=ビルトインのWikiを使用する settings.default_wiki_branch_name=デフォルトのWikiブランチ名 -settings.default_permission_everyone_access=すべてのサインインユーザーにデフォルトで許可するアクセス権限: settings.failed_to_change_default_wiki_branch=デフォルトのWikiブランチを変更できませんでした。 settings.use_external_wiki=外部のWikiを使用する settings.external_wiki_url=外部WikiのURL diff --git a/options/locale/locale_ko-KR.ini b/options/locale/locale_ko-KR.ini index 697371c2c9..ddb80dde1d 100644 --- a/options/locale/locale_ko-KR.ini +++ b/options/locale/locale_ko-KR.ini @@ -707,7 +707,6 @@ issues.filter_label=레이블 issues.filter_label_no_select=모든 레이블 issues.filter_milestone=마일스톤 issues.filter_assignee=담당자 -issues.filter_assginee_no_assignee=담당자 없음 issues.filter_type=유형 issues.filter_type.all_issues=모든 이슈 issues.filter_type.assigned_to_you=나에게 할당됨 diff --git a/options/locale/locale_lv-LV.ini b/options/locale/locale_lv-LV.ini index 4439537fd7..42c12def23 100644 --- a/options/locale/locale_lv-LV.ini +++ b/options/locale/locale_lv-LV.ini @@ -1383,7 +1383,6 @@ issues.filter_project=Projekts issues.filter_project_all=Visi projekti issues.filter_project_none=Nav projekta issues.filter_assignee=Atbildīgais -issues.filter_assginee_no_assignee=Nav atbildīgā issues.filter_poster=Autors issues.filter_type=Veids issues.filter_type.all_issues=Visas problēmas diff --git a/options/locale/locale_nl-NL.ini b/options/locale/locale_nl-NL.ini index 77bf2d2d59..0ad14807d6 100644 --- a/options/locale/locale_nl-NL.ini +++ b/options/locale/locale_nl-NL.ini @@ -1141,7 +1141,6 @@ issues.filter_milestone=Mijlpaal issues.filter_project=Project issues.filter_project_none=Geen project issues.filter_assignee=Aangewezene -issues.filter_assginee_no_assignee=Geen verantwoordelijke issues.filter_poster=Auteur issues.filter_type=Type issues.filter_type.all_issues=Alle kwesties diff --git a/options/locale/locale_pl-PL.ini b/options/locale/locale_pl-PL.ini index f64b8771ac..9673db2a71 100644 --- a/options/locale/locale_pl-PL.ini +++ b/options/locale/locale_pl-PL.ini @@ -1054,7 +1054,6 @@ issues.filter_label_no_select=Wszystkie etykiety issues.filter_milestone=Kamień milowy issues.filter_project_none=Brak projektu issues.filter_assignee=Przypisany -issues.filter_assginee_no_assignee=Brak przypisania issues.filter_type=Typ issues.filter_type.all_issues=Wszystkie zgłoszenia issues.filter_type.assigned_to_you=Przypisane do Ciebie diff --git a/options/locale/locale_pt-PT.ini b/options/locale/locale_pt-PT.ini index 8b4d66a718..4beeeb5b0d 100644 --- a/options/locale/locale_pt-PT.ini +++ b/options/locale/locale_pt-PT.ini @@ -730,8 +730,8 @@ public_profile=Perfil público biography_placeholder=Conte-nos um pouco sobre si! (Pode usar Markdown) location_placeholder=Partilhe a sua localização aproximada com outros profile_desc=Controle como o seu perfil é apresentado aos outros utilizadores. O seu endereço de email principal será usado para notificações, recuperação de senha e operações Git baseadas na web. -password_username_disabled=Não tem permissão para alterar os nomes de utilizador deles/delas. Entre em contacto com o administrador para saber mais detalhes. -password_full_name_disabled=Não tem permissão para alterar o nome completo deles/delas. Entre em contacto com o administrador para saber mais detalhes. +password_username_disabled=Não tem permissão para alterar o seu nome de utilizador. Entre em contacto com o administrador para saber mais detalhes. +password_full_name_disabled=Não tem permissão para alterar o seu nome completo. Entre em contacto com o administrador para saber mais detalhes. full_name=Nome completo website=Sítio web location=Localização @@ -926,6 +926,9 @@ permission_not_set=Não definido permission_no_access=Sem acesso permission_read=Lidas permission_write=Leitura e escrita +permission_anonymous_read=Leitura anónima +permission_everyone_read=Leitura pública +permission_everyone_write=Escrita pública access_token_desc=As permissões dos códigos escolhidos limitam a autorização apenas às rotas da API correspondentes. Leia a documentação para obter mais informação. at_least_one_permission=Tem que escolher pelo menos uma permissão para criar um código permissions_list=Permissões: @@ -1138,6 +1141,7 @@ transfer.no_permission_to_reject=Você não tem permissão para rejeitar esta tr desc.private=Privado desc.public=Público +desc.public_access=Acesso público desc.template=Modelo desc.internal=Interno desc.archived=Arquivado @@ -1546,7 +1550,7 @@ issues.filter_project=Planeamento issues.filter_project_all=Todos os planeamentos issues.filter_project_none=Nenhum planeamento issues.filter_assignee=Encarregado -issues.filter_assginee_no_assignee=Sem encarregado +issues.filter_assignee_no_assignee=Não atribuído issues.filter_assignee_any_assignee=Atribuído a qualquer pessoa issues.filter_poster=Autor(a) issues.filter_user_placeholder=Procurar utilizadores @@ -2132,6 +2136,12 @@ contributors.contribution_type.deletions=Eliminações settings=Configurações settings.desc=Configurações é onde pode gerir as configurações do repositório settings.options=Repositório +settings.public_access=Acesso público +settings.public_access_desc=Configurar as permissões de acesso público do visitante para substituir os valores predefinidos deste repositório. +settings.public_access.docs.not_set=Não definido: nenhuma permissão extra de acesso público. As permissões do visitante seguem a visibilidade e as permissões de membro do repositório. +settings.public_access.docs.anonymous_read=Leitura anónima: utilizadores sem sessão iniciada podem consultar a unidade. +settings.public_access.docs.everyone_read=Leitura pública: todos os utilizadores com sessão iniciada podem aceder à unidade com permissão de leitura. Permissão de leitura das unidades de questões / pedidos de integração também significa que os utilizadores podem criar novas questões / pedidos de integração. +settings.public_access.docs.everyone_write=Escrita pública: Todos os utilizadores com sessão iniciada têm permissão de escrita na unidade. Apenas a unidade Wiki suporta esta permissão. settings.collaboration=Colaboradores settings.collaboration.admin=Administrador settings.collaboration.write=Escrita @@ -2178,7 +2188,6 @@ settings.advanced_settings=Configurações avançadas settings.wiki_desc=Habilitar wiki do repositório settings.use_internal_wiki=Usar o wiki integrado settings.default_wiki_branch_name=Nome do ramo predefinido do wiki -settings.default_permission_everyone_access=Permissão de acesso predefinida para todos os utilizadores registados: settings.failed_to_change_default_wiki_branch=Falhou ao mudar o nome do ramo predefinido do wiki. settings.use_external_wiki=Usar um wiki externo settings.external_wiki_url=URL do wiki externo @@ -2723,6 +2732,7 @@ branch.restore_success=O ramo "%s" foi restaurado. branch.restore_failed=Falhou a restauração do ramo "%s". branch.protected_deletion_failed=O ramo "%s" está protegido, não pode ser eliminado. branch.default_deletion_failed=O ramo "%s" é o ramo principal, não pode ser eliminado. +branch.default_branch_not_exist=O ramo predefinido "%s" não existe. branch.restore=`Restaurar o ramo "%s"` branch.download=`Descarregar o ramo "%s"` branch.rename=`Renomear ramo "%s"` diff --git a/options/locale/locale_ru-RU.ini b/options/locale/locale_ru-RU.ini index fe52165837..68246ff751 100644 --- a/options/locale/locale_ru-RU.ini +++ b/options/locale/locale_ru-RU.ini @@ -1355,7 +1355,6 @@ issues.filter_project=Проект issues.filter_project_all=Все проекты issues.filter_project_none=Нет проекта issues.filter_assignee=Назначено -issues.filter_assginee_no_assignee=Нет ответственного issues.filter_poster=Автор issues.filter_type=Тип issues.filter_type.all_issues=Все задачи diff --git a/options/locale/locale_si-LK.ini b/options/locale/locale_si-LK.ini index 2cd7fb29b9..7c95b254e8 100644 --- a/options/locale/locale_si-LK.ini +++ b/options/locale/locale_si-LK.ini @@ -1025,7 +1025,6 @@ issues.filter_label_no_select=සියලු ලේබල issues.filter_milestone=සන්ධිස්ථානය issues.filter_project_none=ව්යාපෘති නැත issues.filter_assignee=අස්ගිනී -issues.filter_assginee_no_assignee=කිසිදු අස්වැද්දුමක් issues.filter_type=වර්ගය issues.filter_type.all_issues=සියලු ගැටළු issues.filter_type.assigned_to_you=ඔබට පවරා ඇත diff --git a/options/locale/locale_sv-SE.ini b/options/locale/locale_sv-SE.ini index dbe53aaadf..92917c103a 100644 --- a/options/locale/locale_sv-SE.ini +++ b/options/locale/locale_sv-SE.ini @@ -873,7 +873,6 @@ issues.filter_label_no_select=Alla etiketter issues.filter_milestone=Milsten issues.filter_project_none=Inget projekt issues.filter_assignee=Förvärvare -issues.filter_assginee_no_assignee=Ingen tilldelad issues.filter_type=Typ issues.filter_type.all_issues=Alla ärenden issues.filter_type.assigned_to_you=Tilldelad dig diff --git a/options/locale/locale_tr-TR.ini b/options/locale/locale_tr-TR.ini index 1a044fca83..faf442431b 100644 --- a/options/locale/locale_tr-TR.ini +++ b/options/locale/locale_tr-TR.ini @@ -1484,7 +1484,6 @@ issues.filter_project=Proje issues.filter_project_all=Tüm projeler issues.filter_project_none=Proje yok issues.filter_assignee=Atanan -issues.filter_assginee_no_assignee=Atanan yok issues.filter_poster=Yazar issues.filter_type=Tür issues.filter_type.all_issues=Tüm konular diff --git a/options/locale/locale_uk-UA.ini b/options/locale/locale_uk-UA.ini index 8c8911ceb6..995de50b61 100644 --- a/options/locale/locale_uk-UA.ini +++ b/options/locale/locale_uk-UA.ini @@ -1071,7 +1071,6 @@ issues.filter_milestone=Етап issues.filter_project=Проєкт issues.filter_project_none=Проєкт відсутній issues.filter_assignee=Виконавець -issues.filter_assginee_no_assignee=Немає виконавця issues.filter_type=Тип issues.filter_type.all_issues=Всі задачі issues.filter_type.assigned_to_you=Призначене вам diff --git a/options/locale/locale_zh-CN.ini b/options/locale/locale_zh-CN.ini index f36789921e..7f15c32304 100644 --- a/options/locale/locale_zh-CN.ini +++ b/options/locale/locale_zh-CN.ini @@ -718,8 +718,6 @@ public_profile=公开信息 biography_placeholder=告诉我们一点您自己! (您可以使用Markdown) location_placeholder=与他人分享你的大概位置 profile_desc=控制您的个人资料对其他用户的显示方式。您的主要电子邮件地址将用于通知、密码恢复和基于网页界面的 Git 操作 -password_username_disabled=不允许非本地用户更改他们的用户名。更多详情请联系您的系统管理员。 -password_full_name_disabled=您无权更改他们的全名。请联系您的站点管理员了解更多详情。 full_name=自定义名称 website=个人网站 location=所在地区 diff --git a/options/locale/locale_zh-HK.ini b/options/locale/locale_zh-HK.ini index b924faba09..ae6c6c3552 100644 --- a/options/locale/locale_zh-HK.ini +++ b/options/locale/locale_zh-HK.ini @@ -416,7 +416,6 @@ issues.delete_branch_at=`刪除分支 %s %s` issues.filter_label=標籤篩選 issues.filter_milestone=里程碑篩選 issues.filter_assignee=指派人篩選 -issues.filter_assginee_no_assignee=無負責人 issues.filter_type=類型篩選 issues.filter_type.all_issues=所有問題 issues.filter_type.assigned_to_you=指派給您的 diff --git a/options/locale/locale_zh-TW.ini b/options/locale/locale_zh-TW.ini index 10d6676ac5..374ff073f2 100644 --- a/options/locale/locale_zh-TW.ini +++ b/options/locale/locale_zh-TW.ini @@ -714,8 +714,6 @@ public_profile=公開的個人資料 biography_placeholder=告訴我們一些關於您的事情吧! (您可以使用 Markdown) location_placeholder=與其他人分享您的大概位置 profile_desc=控制您的個人檔案會如何呈現給其她使用者。您的主要電子郵件地址會被用於通知、密碼救援以及網頁上的 Git 操作。 -password_username_disabled=非本地使用者不允許更改他們的帳號。詳細資訊請聯絡您的系統管理員。 -password_full_name_disabled=您不被允許更改他們的全名。詳細資訊請聯絡您的系統管理員。 full_name=全名 website=個人網站 location=所在地區 diff --git a/routers/api/actions/artifacts_chunks.go b/routers/api/actions/artifacts_chunks.go index 9d2b69820c..708931d1ac 100644 --- a/routers/api/actions/artifacts_chunks.go +++ b/routers/api/actions/artifacts_chunks.go @@ -51,7 +51,7 @@ func saveUploadChunkBase(st storage.ObjectStorage, ctx *ArtifactContext, log.Info("[artifact] check chunk md5, sum: %s, header: %s", chunkMd5String, reqMd5String) // if md5 not match, delete the chunk if reqMd5String != chunkMd5String { - checkErr = fmt.Errorf("md5 not match") + checkErr = errors.New("md5 not match") } } if writtenSize != contentSize { @@ -261,7 +261,7 @@ func mergeChunksForArtifact(ctx *ArtifactContext, chunks []*chunkFileItem, st st return fmt.Errorf("save merged file error: %v", err) } if written != artifact.FileCompressedSize { - return fmt.Errorf("merged file size is not equal to chunk length") + return errors.New("merged file size is not equal to chunk length") } defer func() { diff --git a/routers/api/actions/artifactsv4.go b/routers/api/actions/artifactsv4.go index 3d992ca2dd..9fb0a31549 100644 --- a/routers/api/actions/artifactsv4.go +++ b/routers/api/actions/artifactsv4.go @@ -170,7 +170,7 @@ func (r artifactV4Routes) buildSignature(endp, expires, artifactName string, tas func (r artifactV4Routes) buildArtifactURL(ctx *ArtifactContext, endp, artifactName string, taskID, artifactID int64) string { expires := time.Now().Add(60 * time.Minute).Format("2006-01-02 15:04:05.999999999 -0700 MST") uploadURL := strings.TrimSuffix(httplib.GuessCurrentAppURL(ctx), "/") + strings.TrimSuffix(r.prefix, "/") + - "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID, artifactID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + fmt.Sprint(taskID) + "&artifactID=" + fmt.Sprint(artifactID) + "/" + endp + "?sig=" + base64.URLEncoding.EncodeToString(r.buildSignature(endp, expires, artifactName, taskID, artifactID)) + "&expires=" + url.QueryEscape(expires) + "&artifactName=" + url.QueryEscape(artifactName) + "&taskID=" + strconv.FormatInt(taskID, 10) + "&artifactID=" + strconv.FormatInt(artifactID, 10) return uploadURL } diff --git a/routers/api/packages/api.go b/routers/api/packages/api.go index 72db15dc26..ae4ea7ea87 100644 --- a/routers/api/packages/api.go +++ b/routers/api/packages/api.go @@ -552,10 +552,10 @@ func CommonRoutes() *web.Router { r.Methods("HEAD,GET,PUT,DELETE", "*", func(ctx *context.Context) { path := ctx.PathParam("*") - isHead := ctx.Req.Method == "HEAD" - isGetHead := ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET" - isPut := ctx.Req.Method == "PUT" - isDelete := ctx.Req.Method == "DELETE" + isHead := ctx.Req.Method == http.MethodHead + isGetHead := ctx.Req.Method == http.MethodHead || ctx.Req.Method == http.MethodGet + isPut := ctx.Req.Method == http.MethodPut + isDelete := ctx.Req.Method == http.MethodDelete m := repoPattern.FindStringSubmatch(path) if len(m) == 2 && isGetHead { diff --git a/routers/api/packages/cargo/cargo.go b/routers/api/packages/cargo/cargo.go index 42ef13476c..710c614c6e 100644 --- a/routers/api/packages/cargo/cargo.go +++ b/routers/api/packages/cargo/cargo.go @@ -51,7 +51,7 @@ func apiError(ctx *context.Context, status int, obj any) { // https://rust-lang.github.io/rfcs/2789-sparse-index.html func RepositoryConfig(ctx *context.Context) { - ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner, setting.Service.RequireSignInView || ctx.Package.Owner.Visibility != structs.VisibleTypePublic)) + ctx.JSON(http.StatusOK, cargo_service.BuildConfig(ctx.Package.Owner, setting.Service.RequireSignInViewStrict || ctx.Package.Owner.Visibility != structs.VisibleTypePublic)) } func EnumeratePackageVersions(ctx *context.Context) { diff --git a/routers/api/packages/chef/auth.go b/routers/api/packages/chef/auth.go index a790e9a363..c6808300a2 100644 --- a/routers/api/packages/chef/auth.go +++ b/routers/api/packages/chef/auth.go @@ -12,6 +12,7 @@ import ( "crypto/x509" "encoding/base64" "encoding/pem" + "errors" "fmt" "hash" "math/big" @@ -121,7 +122,7 @@ func verifyTimestamp(req *http.Request) error { } if diff > maxTimeDifference { - return fmt.Errorf("time difference") + return errors.New("time difference") } return nil @@ -190,7 +191,7 @@ func getAuthorizationData(req *http.Request) ([]byte, error) { tmp := make([]string, len(valueList)) for k, v := range valueList { if k > len(tmp) { - return nil, fmt.Errorf("invalid X-Ops-Authorization headers") + return nil, errors.New("invalid X-Ops-Authorization headers") } tmp[k-1] = v } @@ -267,7 +268,7 @@ func verifyDataOld(signature, data []byte, pub *rsa.PublicKey) error { } if !slices.Equal(out[skip:], data) { - return fmt.Errorf("could not verify signature") + return errors.New("could not verify signature") } return nil diff --git a/routers/api/packages/container/blob.go b/routers/api/packages/container/blob.go index 671803788a..4a2320ab76 100644 --- a/routers/api/packages/container/blob.go +++ b/routers/api/packages/container/blob.go @@ -149,7 +149,7 @@ func getOrCreateUploadVersion(ctx context.Context, pi *packages_service.PackageI } func createFileForBlob(ctx context.Context, pv *packages_model.PackageVersion, pb *packages_model.PackageBlob) error { - filename := strings.ToLower(fmt.Sprintf("sha256_%s", pb.HashSHA256)) + filename := strings.ToLower("sha256_" + pb.HashSHA256) pf := &packages_model.PackageFile{ VersionID: pv.ID, diff --git a/routers/api/packages/container/container.go b/routers/api/packages/container/container.go index bb14db9db7..6ef1655235 100644 --- a/routers/api/packages/container/container.go +++ b/routers/api/packages/container/container.go @@ -126,7 +126,7 @@ func apiUnauthorizedError(ctx *context.Context) { // ReqContainerAccess is a middleware which checks the current user valid (real user or ghost if anonymous access is enabled) func ReqContainerAccess(ctx *context.Context) { - if ctx.Doer == nil || (setting.Service.RequireSignInView && ctx.Doer.IsGhost()) { + if ctx.Doer == nil || (setting.Service.RequireSignInViewStrict && ctx.Doer.IsGhost()) { apiUnauthorizedError(ctx) } } @@ -152,7 +152,7 @@ func Authenticate(ctx *context.Context) { u := ctx.Doer packageScope := auth_service.GetAccessScope(ctx.Data) if u == nil { - if setting.Service.RequireSignInView { + if setting.Service.RequireSignInViewStrict { apiUnauthorizedError(ctx) return } diff --git a/routers/api/packages/container/manifest.go b/routers/api/packages/container/manifest.go index ad035cf473..26faa7b024 100644 --- a/routers/api/packages/container/manifest.go +++ b/routers/api/packages/container/manifest.go @@ -406,7 +406,7 @@ func createFileFromBlobReference(ctx context.Context, pv, uploadVersion *package } if ref.Name == "" { - ref.Name = strings.ToLower(fmt.Sprintf("sha256_%s", ref.File.Blob.HashSHA256)) + ref.Name = strings.ToLower("sha256_" + ref.File.Blob.HashSHA256) } pf := &packages_model.PackageFile{ diff --git a/routers/api/packages/nuget/nuget.go b/routers/api/packages/nuget/nuget.go index 07a8de0a68..fa5067a278 100644 --- a/routers/api/packages/nuget/nuget.go +++ b/routers/api/packages/nuget/nuget.go @@ -488,7 +488,7 @@ func UploadPackage(ctx *context.Context) { pv, &packages_service.PackageFileCreationInfo{ PackageFileInfo: packages_service.PackageFileInfo{ - Filename: strings.ToLower(fmt.Sprintf("%s.nuspec", np.ID)), + Filename: strings.ToLower(np.ID + ".nuspec"), }, Data: nuspecBuf, }, diff --git a/routers/api/v1/activitypub/reqsignature.go b/routers/api/v1/activitypub/reqsignature.go index 957d593d89..4eff51782f 100644 --- a/routers/api/v1/activitypub/reqsignature.go +++ b/routers/api/v1/activitypub/reqsignature.go @@ -7,6 +7,7 @@ import ( "crypto" "crypto/x509" "encoding/pem" + "errors" "fmt" "io" "net/http" @@ -34,7 +35,7 @@ func getPublicKeyFromResponse(b []byte, keyID *url.URL) (p crypto.PublicKey, err pubKeyPem := pubKey.PublicKeyPem block, _ := pem.Decode([]byte(pubKeyPem)) if block == nil || block.Type != "PUBLIC KEY" { - return nil, fmt.Errorf("could not decode publicKeyPem to PUBLIC KEY pem block type") + return nil, errors.New("could not decode publicKeyPem to PUBLIC KEY pem block type") } p, err = x509.ParsePKIXPublicKey(block.Bytes) return p, err diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go index c4bb85de55..3ba77604ec 100644 --- a/routers/api/v1/admin/user.go +++ b/routers/api/v1/admin/user.go @@ -296,7 +296,7 @@ func DeleteUser(ctx *context.APIContext) { // admin should not delete themself if ctx.ContextUser.ID == ctx.Doer.ID { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("you cannot delete yourself")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("you cannot delete yourself")) return } diff --git a/routers/api/v1/api.go b/routers/api/v1/api.go index 14f568fd1c..5cd08a3618 100644 --- a/routers/api/v1/api.go +++ b/routers/api/v1/api.go @@ -307,7 +307,7 @@ func tokenRequiresScopes(requiredScopeCategories ...auth_model.AccessTokenScopeC // use the http method to determine the access level requiredScopeLevel := auth_model.Read - if ctx.Req.Method == "POST" || ctx.Req.Method == "PUT" || ctx.Req.Method == "PATCH" || ctx.Req.Method == "DELETE" { + if ctx.Req.Method == http.MethodPost || ctx.Req.Method == http.MethodPut || ctx.Req.Method == http.MethodPatch || ctx.Req.Method == http.MethodDelete { requiredScopeLevel = auth_model.Write } @@ -355,7 +355,7 @@ func reqToken() func(ctx *context.APIContext) { func reqExploreSignIn() func(ctx *context.APIContext) { return func(ctx *context.APIContext) { - if (setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned { + if (setting.Service.RequireSignInViewStrict || setting.Service.Explore.RequireSigninView) && !ctx.IsSigned { ctx.APIError(http.StatusUnauthorized, "you must be signed in to search for users") } } @@ -886,7 +886,7 @@ func Routes() *web.Router { m.Use(apiAuth(buildAuthGroup())) m.Use(verifyAuthWithOptions(&common.VerifyOptions{ - SignInRequired: setting.Service.RequireSignInView, + SignInRequired: setting.Service.RequireSignInViewStrict, })) addActionsRoutes := func( diff --git a/routers/api/v1/misc/markup_test.go b/routers/api/v1/misc/markup_test.go index 6063e54cdc..38a1a3be9e 100644 --- a/routers/api/v1/misc/markup_test.go +++ b/routers/api/v1/misc/markup_test.go @@ -134,7 +134,7 @@ Here are some links to the most important topics. You can find the full list of Quick Links Here are some links to the most important topics. You can find the full list of pages at the sidebar. Configuration - + `, } @@ -158,19 +158,19 @@ Here are some links to the most important topics. You can find the full list of input := "[Link](test.md)\n" testRenderMarkdown(t, "gfm", false, input, `Link - + `, http.StatusOK) testRenderMarkdown(t, "gfm", false, input, `Link - + `, http.StatusOK) testRenderMarkup(t, "gfm", false, "", input, `Link - + `, http.StatusOK) testRenderMarkup(t, "file", false, "path/new-file.md", input, `Link - + `, http.StatusOK) testRenderMarkup(t, "file", false, "path/test.unknown", "## Test", "unsupported file to render: \"path/test.unknown\"\n", http.StatusUnprocessableEntity) diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go index 9c6e572fb4..fe82550fdd 100644 --- a/routers/api/v1/repo/branch.go +++ b/routers/api/v1/repo/branch.go @@ -6,7 +6,6 @@ package repo import ( "errors" - "fmt" "net/http" "code.gitea.io/gitea/models/db" @@ -60,17 +59,16 @@ func GetBranch(ctx *context.APIContext) { branchName := ctx.PathParam("*") - branch, err := ctx.Repo.GitRepo.GetBranch(branchName) + exist, err := git_model.IsBranchExist(ctx, ctx.Repo.Repository.ID, branchName) if err != nil { - if git.IsErrBranchNotExist(err) { - ctx.APIErrorNotFound(err) - } else { - ctx.APIErrorInternal(err) - } + ctx.APIErrorInternal(err) + return + } else if !exist { + ctx.APIErrorNotFound(err) return } - c, err := branch.GetCommit() + c, err := ctx.Repo.GitRepo.GetBranchCommit(branchName) if err != nil { ctx.APIErrorInternal(err) return @@ -82,7 +80,7 @@ func GetBranch(ctx *context.APIContext) { return } - br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) + br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branchName, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) if err != nil { ctx.APIErrorInternal(err) return @@ -157,9 +155,9 @@ func DeleteBranch(ctx *context.APIContext) { case git.IsErrBranchNotExist(err): ctx.APIErrorNotFound(err) case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.APIError(http.StatusForbidden, fmt.Errorf("can not delete default branch")) + ctx.APIError(http.StatusForbidden, errors.New("can not delete default branch")) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.APIError(http.StatusForbidden, fmt.Errorf("branch protected")) + ctx.APIError(http.StatusForbidden, errors.New("branch protected")) default: ctx.APIErrorInternal(err) } @@ -261,25 +259,19 @@ func CreateBranch(ctx *context.APIContext) { return } - branch, err := ctx.Repo.GitRepo.GetBranch(opt.BranchName) + commit, err := ctx.Repo.GitRepo.GetBranchCommit(opt.BranchName) if err != nil { ctx.APIErrorInternal(err) return } - commit, err := branch.GetCommit() + branchProtection, err := git_model.GetFirstMatchProtectedBranchRule(ctx, ctx.Repo.Repository.ID, opt.BranchName) if err != nil { ctx.APIErrorInternal(err) return } - branchProtection, err := git_model.GetFirstMatchProtectedBranchRule(ctx, ctx.Repo.Repository.ID, branch.Name) - if err != nil { - ctx.APIErrorInternal(err) - return - } - - br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) + br, err := convert.ToBranch(ctx, ctx.Repo.Repository, opt.BranchName, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin()) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/commits.go b/routers/api/v1/repo/commits.go index 03489d777b..34a81bd7f3 100644 --- a/routers/api/v1/repo/commits.go +++ b/routers/api/v1/repo/commits.go @@ -5,7 +5,6 @@ package repo import ( - "fmt" "math" "net/http" "strconv" @@ -65,7 +64,7 @@ func GetSingleCommit(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("no valid ref or sha: %s", sha)) + ctx.APIError(http.StatusUnprocessableEntity, "no valid ref or sha: "+sha) return } @@ -180,13 +179,7 @@ func GetAllCommits(ctx *context.APIContext) { var baseCommit *git.Commit if len(sha) == 0 { // no sha supplied - use default branch - head, err := ctx.Repo.GitRepo.GetHEADBranch() - if err != nil { - ctx.APIErrorInternal(err) - return - } - - baseCommit, err = ctx.Repo.GitRepo.GetBranchCommit(head.Name) + baseCommit, err = ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) if err != nil { ctx.APIErrorInternal(err) return diff --git a/routers/api/v1/repo/download.go b/routers/api/v1/repo/download.go index 20901badfb..acd93ecf2e 100644 --- a/routers/api/v1/repo/download.go +++ b/routers/api/v1/repo/download.go @@ -4,7 +4,6 @@ package repo import ( - "fmt" "net/http" "code.gitea.io/gitea/modules/git" @@ -23,7 +22,7 @@ func DownloadArchive(ctx *context.APIContext) { case "bundle": tp = git.ArchiveBundle default: - ctx.APIError(http.StatusBadRequest, fmt.Sprintf("Unknown archive type: %s", ballType)) + ctx.APIError(http.StatusBadRequest, "Unknown archive type: "+ballType) return } diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go index 1ba71aa8a3..d8e9fde2c0 100644 --- a/routers/api/v1/repo/file.go +++ b/routers/api/v1/repo/file.go @@ -661,7 +661,7 @@ func UpdateFile(ctx *context.APIContext) { // "$ref": "#/responses/repoArchivedError" apiOpts := web.GetForm(ctx).(*api.UpdateFileOptions) if ctx.Repo.Repository.IsEmpty { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("repo is empty")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("repo is empty")) return } diff --git a/routers/api/v1/repo/hook_test.go b/routers/api/v1/repo/hook_test.go index 2d15c6e078..f8d61ccf00 100644 --- a/routers/api/v1/repo/hook_test.go +++ b/routers/api/v1/repo/hook_test.go @@ -23,7 +23,7 @@ func TestTestHook(t *testing.T) { contexttest.LoadRepoCommit(t, ctx) contexttest.LoadUser(t, ctx, 2) TestHook(ctx) - assert.EqualValues(t, http.StatusNoContent, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusNoContent, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &webhook.HookTask{ HookID: 1, diff --git a/routers/api/v1/repo/issue_label.go b/routers/api/v1/repo/issue_label.go index f8e14e0490..d5eee2d469 100644 --- a/routers/api/v1/repo/issue_label.go +++ b/routers/api/v1/repo/issue_label.go @@ -5,7 +5,7 @@ package repo import ( - "fmt" + "errors" "net/http" "reflect" @@ -321,7 +321,7 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) if !ctx.Repo.CanWriteIssuesOrPulls(issue.IsPull) { ctx.APIError(http.StatusForbidden, "write permission is required") - return nil, nil, fmt.Errorf("permission denied") + return nil, nil, errors.New("permission denied") } var ( @@ -337,12 +337,12 @@ func prepareForReplaceOrAdd(ctx *context.APIContext, form api.IssueLabelsOption) labelNames = append(labelNames, rv.String()) default: ctx.APIError(http.StatusBadRequest, "a label must be an integer or a string") - return nil, nil, fmt.Errorf("invalid label") + return nil, nil, errors.New("invalid label") } } if len(labelIDs) > 0 && len(labelNames) > 0 { ctx.APIError(http.StatusBadRequest, "labels should be an array of strings or integers") - return nil, nil, fmt.Errorf("invalid labels") + return nil, nil, errors.New("invalid labels") } if len(labelNames) > 0 { repoLabelIDs, err := issues_model.GetLabelIDsInRepoByNames(ctx, ctx.Repo.Repository.ID, labelNames) diff --git a/routers/api/v1/repo/issue_tracked_time.go b/routers/api/v1/repo/issue_tracked_time.go index dbb2afa920..49531f1824 100644 --- a/routers/api/v1/repo/issue_tracked_time.go +++ b/routers/api/v1/repo/issue_tracked_time.go @@ -4,6 +4,7 @@ package repo import ( + "errors" "fmt" "net/http" "time" @@ -116,7 +117,7 @@ func ListTrackedTimes(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) return } } @@ -437,7 +438,7 @@ func ListTrackedTimesByUser(ctx *context.APIContext) { } if !ctx.IsUserRepoAdmin() && !ctx.Doer.IsAdmin && ctx.Doer.ID != user.ID { - ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) return } @@ -545,7 +546,7 @@ func ListTrackedTimesByRepository(ctx *context.APIContext) { if opts.UserID == 0 { opts.UserID = ctx.Doer.ID } else { - ctx.APIError(http.StatusForbidden, fmt.Errorf("query by user not allowed; not enough rights")) + ctx.APIError(http.StatusForbidden, errors.New("query by user not allowed; not enough rights")) return } } diff --git a/routers/api/v1/repo/migrate.go b/routers/api/v1/repo/migrate.go index d7508684a1..87bb269031 100644 --- a/routers/api/v1/repo/migrate.go +++ b/routers/api/v1/repo/migrate.go @@ -115,12 +115,12 @@ func Migrate(ctx *context.APIContext) { gitServiceType := convert.ToGitServiceType(form.Service) if form.Mirror && setting.Mirror.DisableNewPull { - ctx.APIError(http.StatusForbidden, fmt.Errorf("the site administrator has disabled the creation of new pull mirrors")) + ctx.APIError(http.StatusForbidden, errors.New("the site administrator has disabled the creation of new pull mirrors")) return } if setting.Repository.DisableMigrations { - ctx.APIError(http.StatusForbidden, fmt.Errorf("the site administrator has disabled migrations")) + ctx.APIError(http.StatusForbidden, errors.New("the site administrator has disabled migrations")) return } diff --git a/routers/api/v1/repo/mirror.go b/routers/api/v1/repo/mirror.go index b5f4c12c50..f11a1603c4 100644 --- a/routers/api/v1/repo/mirror.go +++ b/routers/api/v1/repo/mirror.go @@ -5,7 +5,6 @@ package repo import ( "errors" - "fmt" "net/http" "time" @@ -367,7 +366,7 @@ func CreatePushMirror(ctx *context.APIContext, mirrorOption *api.CreatePushMirro pushMirror := &repo_model.PushMirror{ RepoID: repo.ID, Repo: repo, - RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix), + RemoteName: "remote_mirror_" + remoteSuffix, Interval: interval, SyncOnCommit: mirrorOption.SyncOnCommit, RemoteAddress: remoteAddress, diff --git a/routers/api/v1/repo/notes.go b/routers/api/v1/repo/notes.go index dcb512256c..eb048df6fe 100644 --- a/routers/api/v1/repo/notes.go +++ b/routers/api/v1/repo/notes.go @@ -4,7 +4,7 @@ package repo import ( - "fmt" + "errors" "net/http" "code.gitea.io/gitea/modules/git" @@ -54,7 +54,7 @@ func GetNote(ctx *context.APIContext) { sha := ctx.PathParam("sha") if !git.IsValidRefPattern(sha) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("no valid ref or sha: %s", sha)) + ctx.APIError(http.StatusUnprocessableEntity, "no valid ref or sha: "+sha) return } getNote(ctx, sha) @@ -62,7 +62,7 @@ func GetNote(ctx *context.APIContext) { func getNote(ctx *context.APIContext, identifier string) { if ctx.Repo.GitRepo == nil { - ctx.APIErrorInternal(fmt.Errorf("no open git repo")) + ctx.APIErrorInternal(errors.New("no open git repo")) return } diff --git a/routers/api/v1/repo/pull.go b/routers/api/v1/repo/pull.go index f5d0e37c65..c0b1810191 100644 --- a/routers/api/v1/repo/pull.go +++ b/routers/api/v1/repo/pull.go @@ -1054,9 +1054,9 @@ func MergePullRequest(ctx *context.APIContext) { case git.IsErrBranchNotExist(err): ctx.APIErrorNotFound(err) case errors.Is(err, repo_service.ErrBranchIsDefault): - ctx.APIError(http.StatusForbidden, fmt.Errorf("can not delete default branch")) + ctx.APIError(http.StatusForbidden, errors.New("can not delete default branch")) case errors.Is(err, git_model.ErrBranchIsProtected): - ctx.APIError(http.StatusForbidden, fmt.Errorf("branch protected")) + ctx.APIError(http.StatusForbidden, errors.New("branch protected")) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/repo/pull_review.go b/routers/api/v1/repo/pull_review.go index fb35126a99..9421a052db 100644 --- a/routers/api/v1/repo/pull_review.go +++ b/routers/api/v1/repo/pull_review.go @@ -439,7 +439,7 @@ func SubmitPullReview(ctx *context.APIContext) { } if review.Type != issues_model.ReviewTypePending { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("only a pending review can be submitted")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("only a pending review can be submitted")) return } @@ -451,7 +451,7 @@ func SubmitPullReview(ctx *context.APIContext) { // if review stay pending return if reviewType == issues_model.ReviewTypePending { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("review stay pending")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("review stay pending")) return } @@ -496,7 +496,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest case api.ReviewStateApproved: // can not approve your own PR if pr.Issue.IsPoster(ctx.Doer.ID) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("approve your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("approve your own pull is not allowed")) return -1, true } reviewType = issues_model.ReviewTypeApprove @@ -505,7 +505,7 @@ func preparePullReviewType(ctx *context.APIContext, pr *issues_model.PullRequest case api.ReviewStateRequestChanges: // can not reject your own PR if pr.Issue.IsPoster(ctx.Doer.ID) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("reject your own pull is not allowed")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("reject your own pull is not allowed")) return -1, true } reviewType = issues_model.ReviewTypeReject diff --git a/routers/api/v1/repo/release.go b/routers/api/v1/repo/release.go index 36fff126e1..b6f5a3ac9e 100644 --- a/routers/api/v1/repo/release.go +++ b/routers/api/v1/repo/release.go @@ -4,6 +4,7 @@ package repo import ( + "errors" "fmt" "net/http" @@ -220,7 +221,7 @@ func CreateRelease(ctx *context.APIContext) { form := web.GetForm(ctx).(*api.CreateReleaseOption) if ctx.Repo.Repository.IsEmpty { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Errorf("repo is empty")) + ctx.APIError(http.StatusUnprocessableEntity, errors.New("repo is empty")) return } rel, err := repo_model.GetRelease(ctx, ctx.Repo.Repository.ID, form.TagName) diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go index 3d638cb05e..7caf004b4a 100644 --- a/routers/api/v1/repo/repo.go +++ b/routers/api/v1/repo/repo.go @@ -5,6 +5,7 @@ package repo import ( + "errors" "fmt" "net/http" "slices" @@ -711,7 +712,7 @@ func updateBasicProperties(ctx *context.APIContext, opts api.EditRepoOption) err visibilityChanged = repo.IsPrivate != *opts.Private // when ForcePrivate enabled, you could change public repo to private, but only admin users can change private to public if visibilityChanged && setting.Repository.ForcePrivate && !*opts.Private && !ctx.Doer.IsAdmin { - err := fmt.Errorf("cannot change private repository to public") + err := errors.New("cannot change private repository to public") ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -780,12 +781,12 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if newHasIssues && opts.ExternalTracker != nil && !unit_model.TypeExternalTracker.UnitGlobalDisabled() { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalTracker.ExternalTrackerURL) { - err := fmt.Errorf("External tracker URL not valid") + err := errors.New("External tracker URL not valid") ctx.APIError(http.StatusUnprocessableEntity, err) return err } if len(opts.ExternalTracker.ExternalTrackerFormat) != 0 && !validation.IsValidExternalTrackerURLFormat(opts.ExternalTracker.ExternalTrackerFormat) { - err := fmt.Errorf("External tracker URL format not valid") + err := errors.New("External tracker URL format not valid") ctx.APIError(http.StatusUnprocessableEntity, err) return err } @@ -847,7 +848,7 @@ func updateRepoUnits(ctx *context.APIContext, opts api.EditRepoOption) error { if newHasWiki && opts.ExternalWiki != nil && !unit_model.TypeExternalWiki.UnitGlobalDisabled() { // Check that values are valid if !validation.IsValidExternalURL(opts.ExternalWiki.ExternalWikiURL) { - err := fmt.Errorf("External wiki URL not valid") + err := errors.New("External wiki URL not valid") ctx.APIError(http.StatusUnprocessableEntity, "Invalid external wiki URL") return err } @@ -1038,7 +1039,7 @@ func updateRepoArchivedState(ctx *context.APIContext, opts api.EditRepoOption) e // archive / un-archive if opts.Archived != nil { if repo.IsMirror { - err := fmt.Errorf("repo is a mirror, cannot archive/un-archive") + err := errors.New("repo is a mirror, cannot archive/un-archive") ctx.APIError(http.StatusUnprocessableEntity, err) return err } diff --git a/routers/api/v1/repo/repo_test.go b/routers/api/v1/repo/repo_test.go index 0a63b16a99..97233f85dc 100644 --- a/routers/api/v1/repo/repo_test.go +++ b/routers/api/v1/repo/repo_test.go @@ -58,7 +58,7 @@ func TestRepoEdit(t *testing.T) { web.SetForm(ctx, &opts) Edit(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ ID: 1, }, unittest.Cond("name = ? AND is_archived = 1", *opts.Name)) @@ -78,7 +78,7 @@ func TestRepoEditNameChange(t *testing.T) { web.SetForm(ctx, &opts) Edit(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ ID: 1, diff --git a/routers/api/v1/repo/tag.go b/routers/api/v1/repo/tag.go index 2e6c1c1023..e71c6fb443 100644 --- a/routers/api/v1/repo/tag.go +++ b/routers/api/v1/repo/tag.go @@ -110,7 +110,7 @@ func GetAnnotatedTag(ctx *context.APIContext) { if tag, err := ctx.Repo.GitRepo.GetAnnotatedTag(sha); err != nil { ctx.APIError(http.StatusBadRequest, err) } else { - commit, err := tag.Commit(ctx.Repo.GitRepo) + commit, err := ctx.Repo.GitRepo.GetTagCommit(tag.Name) if err != nil { ctx.APIError(http.StatusBadRequest, err) } diff --git a/routers/api/v1/repo/transfer.go b/routers/api/v1/repo/transfer.go index 7b890c9e5c..cbf3d10c39 100644 --- a/routers/api/v1/repo/transfer.go +++ b/routers/api/v1/repo/transfer.go @@ -108,19 +108,16 @@ func Transfer(ctx *context.APIContext) { oldFullname := ctx.Repo.Repository.FullName() if err := repo_service.StartRepositoryTransfer(ctx, ctx.Doer, newOwner, ctx.Repo.Repository, teams); err != nil { - if repo_model.IsErrRepoTransferInProgress(err) { + switch { + case repo_model.IsErrRepoTransferInProgress(err): ctx.APIError(http.StatusConflict, err) - return - } - - if repo_model.IsErrRepoAlreadyExist(err) { + case repo_model.IsErrRepoAlreadyExist(err): ctx.APIError(http.StatusUnprocessableEntity, err) - return - } - - if errors.Is(err, user_model.ErrBlockedUser) { + case repo_service.IsRepositoryLimitReached(err): ctx.APIError(http.StatusForbidden, err) - } else { + case errors.Is(err, user_model.ErrBlockedUser): + ctx.APIError(http.StatusForbidden, err) + default: ctx.APIErrorInternal(err) } return @@ -169,6 +166,8 @@ func AcceptTransfer(ctx *context.APIContext) { ctx.APIError(http.StatusNotFound, err) case errors.Is(err, util.ErrPermissionDenied): ctx.APIError(http.StatusForbidden, err) + case repo_service.IsRepositoryLimitReached(err): + ctx.APIError(http.StatusForbidden, err) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/gpg_key.go b/routers/api/v1/user/gpg_key.go index 504e74ae10..b76bd8a1ee 100644 --- a/routers/api/v1/user/gpg_key.go +++ b/routers/api/v1/user/gpg_key.go @@ -4,7 +4,7 @@ package user import ( - "fmt" + "errors" "net/http" "strings" @@ -135,7 +135,7 @@ func GetGPGKey(ctx *context.APIContext) { // CreateUserGPGKey creates new GPG key to given user by ID. func CreateUserGPGKey(ctx *context.APIContext, form api.CreateGPGKeyOption, uid int64) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.APIErrorNotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", errors.New("gpg keys setting is not allowed to be visited")) return } @@ -205,7 +205,7 @@ func VerifyUserGPGKey(ctx *context.APIContext) { if err != nil { if asymkey_model.IsErrGPGInvalidTokenSignature(err) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) + ctx.APIError(http.StatusUnprocessableEntity, "The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token) return } ctx.APIErrorInternal(err) @@ -276,7 +276,7 @@ func DeleteGPGKey(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.APIErrorNotFound("Not Found", fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", errors.New("gpg keys setting is not allowed to be visited")) return } @@ -302,9 +302,9 @@ func HandleAddGPGKeyError(ctx *context.APIContext, err error, token string) { case asymkey_model.IsErrGPGKeyParsing(err): ctx.APIError(http.StatusUnprocessableEntity, err) case asymkey_model.IsErrGPGNoEmailFound(err): - ctx.APIError(http.StatusNotFound, fmt.Sprintf("None of the emails attached to the GPG key could be found. It may still be added if you provide a valid signature for the token: %s", token)) + ctx.APIError(http.StatusNotFound, "None of the emails attached to the GPG key could be found. It may still be added if you provide a valid signature for the token: "+token) case asymkey_model.IsErrGPGInvalidTokenSignature(err): - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: %s", token)) + ctx.APIError(http.StatusUnprocessableEntity, "The provided GPG key, signature and token do not match or token is out of date. Provide a valid signature for the token: "+token) default: ctx.APIErrorInternal(err) } diff --git a/routers/api/v1/user/key.go b/routers/api/v1/user/key.go index 04854f2092..628f5d6cac 100644 --- a/routers/api/v1/user/key.go +++ b/routers/api/v1/user/key.go @@ -5,7 +5,7 @@ package user import ( std_ctx "context" - "fmt" + "errors" "net/http" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -201,7 +201,7 @@ func GetPublicKey(ctx *context.APIContext) { // CreateUserPublicKey creates new public key to given user by ID. func CreateUserPublicKey(ctx *context.APIContext, form api.CreateKeyOption, uid int64) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.APIErrorNotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", errors.New("ssh keys setting is not allowed to be visited")) return } @@ -271,7 +271,7 @@ func DeletePublicKey(ctx *context.APIContext) { // "$ref": "#/responses/notFound" if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.APIErrorNotFound("Not Found", fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.APIErrorNotFound("Not Found", errors.New("ssh keys setting is not allowed to be visited")) return } diff --git a/routers/api/v1/utils/git.go b/routers/api/v1/utils/git.go index af672ba147..7d276d9d98 100644 --- a/routers/api/v1/utils/git.go +++ b/routers/api/v1/utils/git.go @@ -5,6 +5,7 @@ package utils import ( gocontext "context" + "errors" "fmt" "net/http" @@ -50,7 +51,7 @@ func ResolveRefOrSha(ctx *context.APIContext, ref string) string { // GetGitRefs return git references based on filter func GetGitRefs(ctx *context.APIContext, filter string) ([]*git.Reference, string, error) { if ctx.Repo.GitRepo == nil { - return nil, "", fmt.Errorf("no open git repo found in context") + return nil, "", errors.New("no open git repo found in context") } if len(filter) > 0 { filter = "refs/" + filter diff --git a/routers/api/v1/utils/hook.go b/routers/api/v1/utils/hook.go index ce0c1b5097..532d157e35 100644 --- a/routers/api/v1/utils/hook.go +++ b/routers/api/v1/utils/hook.go @@ -4,7 +4,6 @@ package utils import ( - "fmt" "net/http" "strconv" "strings" @@ -80,7 +79,7 @@ func GetRepoHook(ctx *context.APIContext, repoID, hookID int64) (*webhook.Webhoo // write the appropriate error to `ctx`. Return whether the form is valid func checkCreateHookOption(ctx *context.APIContext, form *api.CreateHookOption) bool { if !webhook_service.IsValidHookTaskType(form.Type) { - ctx.APIError(http.StatusUnprocessableEntity, fmt.Sprintf("Invalid hook type: %s", form.Type)) + ctx.APIError(http.StatusUnprocessableEntity, "Invalid hook type: "+form.Type) return false } for _, name := range []string{"url", "content_type"} { diff --git a/routers/common/blockexpensive.go b/routers/common/blockexpensive.go new file mode 100644 index 0000000000..f52aa2b709 --- /dev/null +++ b/routers/common/blockexpensive.go @@ -0,0 +1,90 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package common + +import ( + "net/http" + "strings" + + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/reqctx" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/web/middleware" + + "github.com/go-chi/chi/v5" +) + +func BlockExpensive() func(next http.Handler) http.Handler { + if !setting.Service.BlockAnonymousAccessExpensive { + return nil + } + return func(next http.Handler) http.Handler { + return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { + ret := determineRequestPriority(reqctx.FromContext(req.Context())) + if !ret.SignedIn { + if ret.Expensive || ret.LongPolling { + http.Redirect(w, req, setting.AppSubURL+"/user/login", http.StatusSeeOther) + return + } + } + next.ServeHTTP(w, req) + }) + } +} + +func isRoutePathExpensive(routePattern string) bool { + if strings.HasPrefix(routePattern, "/user/") || strings.HasPrefix(routePattern, "/login/") { + return false + } + + expensivePaths := []string{ + // code related + "/{username}/{reponame}/archive/", + "/{username}/{reponame}/blame/", + "/{username}/{reponame}/commit/", + "/{username}/{reponame}/commits/", + "/{username}/{reponame}/graph", + "/{username}/{reponame}/media/", + "/{username}/{reponame}/raw/", + "/{username}/{reponame}/src/", + + // issue & PR related (no trailing slash) + "/{username}/{reponame}/issues", + "/{username}/{reponame}/{type:issues}", + "/{username}/{reponame}/pulls", + "/{username}/{reponame}/{type:pulls}", + + // wiki + "/{username}/{reponame}/wiki/", + + // activity + "/{username}/{reponame}/activity/", + } + for _, path := range expensivePaths { + if strings.HasPrefix(routePattern, path) { + return true + } + } + return false +} + +func isRoutePathForLongPolling(routePattern string) bool { + return routePattern == "/user/events" +} + +func determineRequestPriority(reqCtx reqctx.RequestContext) (ret struct { + SignedIn bool + Expensive bool + LongPolling bool +}, +) { + chiRoutePath := chi.RouteContext(reqCtx).RoutePattern() + if _, ok := reqCtx.GetData()[middleware.ContextDataKeySignedUser].(*user_model.User); ok { + ret.SignedIn = true + } else { + ret.Expensive = isRoutePathExpensive(chiRoutePath) + ret.LongPolling = isRoutePathForLongPolling(chiRoutePath) + } + return ret +} diff --git a/routers/common/blockexpensive_test.go b/routers/common/blockexpensive_test.go new file mode 100644 index 0000000000..db5c0db7dd --- /dev/null +++ b/routers/common/blockexpensive_test.go @@ -0,0 +1,30 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package common + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestBlockExpensive(t *testing.T) { + cases := []struct { + expensive bool + routePath string + }{ + {false, "/user/xxx"}, + {false, "/login/xxx"}, + {true, "/{username}/{reponame}/archive/xxx"}, + {true, "/{username}/{reponame}/graph"}, + {true, "/{username}/{reponame}/src/xxx"}, + {true, "/{username}/{reponame}/wiki/xxx"}, + {true, "/{username}/{reponame}/activity/xxx"}, + } + for _, c := range cases { + assert.Equal(t, c.expensive, isRoutePathExpensive(c.routePath), "routePath: %s", c.routePath) + } + + assert.True(t, isRoutePathForLongPolling("/user/events")) +} diff --git a/routers/common/db.go b/routers/common/db.go index cb163c867d..01c0261427 100644 --- a/routers/common/db.go +++ b/routers/common/db.go @@ -5,7 +5,7 @@ package common import ( "context" - "fmt" + "errors" "time" "code.gitea.io/gitea/models/db" @@ -25,7 +25,7 @@ func InitDBEngine(ctx context.Context) (err error) { for i := 0; i < setting.Database.DBConnectRetries; i++ { select { case <-ctx.Done(): - return fmt.Errorf("Aborted due to shutdown:\nin retry ORM engine initialization") + return errors.New("Aborted due to shutdown:\nin retry ORM engine initialization") default: } log.Info("ORM engine initialization attempt #%d/%d...", i+1, setting.Database.DBConnectRetries) diff --git a/routers/common/markup.go b/routers/common/markup.go index 60bf0dba54..4c77ff33ed 100644 --- a/routers/common/markup.go +++ b/routers/common/markup.go @@ -88,7 +88,7 @@ func RenderMarkup(ctx *context.Base, ctxRepo *context.Repository, mode, text, ur }) rctx = rctx.WithMarkupType("").WithRelativePath(filePath) // render the repo file content by its extension default: - ctx.HTTPError(http.StatusUnprocessableEntity, fmt.Sprintf("Unknown mode: %s", mode)) + ctx.HTTPError(http.StatusUnprocessableEntity, "Unknown mode: "+mode) return } rctx = rctx.WithUseAbsoluteLink(true) diff --git a/routers/install/install.go b/routers/install/install.go index b81a5680d3..2962f3948f 100644 --- a/routers/install/install.go +++ b/routers/install/install.go @@ -5,7 +5,6 @@ package install import ( - "fmt" "net/http" "net/mail" "os" @@ -151,7 +150,7 @@ func Install(ctx *context.Context) { form.DisableRegistration = setting.Service.DisableRegistration form.AllowOnlyExternalRegistration = setting.Service.AllowOnlyExternalRegistration form.EnableCaptcha = setting.Service.EnableCaptcha - form.RequireSignInView = setting.Service.RequireSignInView + form.RequireSignInView = setting.Service.RequireSignInViewStrict form.DefaultKeepEmailPrivate = setting.Service.DefaultKeepEmailPrivate form.DefaultAllowCreateOrganization = setting.Service.DefaultAllowCreateOrganization form.DefaultEnableTimetracking = setting.Service.DefaultEnableTimetracking @@ -398,7 +397,7 @@ func SubmitInstall(ctx *context.Context) { cfg.Section("server").Key("DISABLE_SSH").SetValue("true") } else { cfg.Section("server").Key("DISABLE_SSH").SetValue("false") - cfg.Section("server").Key("SSH_PORT").SetValue(fmt.Sprint(form.SSHPort)) + cfg.Section("server").Key("SSH_PORT").SetValue(strconv.Itoa(form.SSHPort)) } if form.LFSRootPath != "" { @@ -429,10 +428,10 @@ func SubmitInstall(ctx *context.Context) { } else { cfg.Section("mailer").Key("ENABLED").SetValue("false") } - cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(fmt.Sprint(form.RegisterConfirm)) - cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(fmt.Sprint(form.MailNotify)) + cfg.Section("service").Key("REGISTER_EMAIL_CONFIRM").SetValue(strconv.FormatBool(form.RegisterConfirm)) + cfg.Section("service").Key("ENABLE_NOTIFY_MAIL").SetValue(strconv.FormatBool(form.MailNotify)) - cfg.Section("server").Key("OFFLINE_MODE").SetValue(fmt.Sprint(form.OfflineMode)) + cfg.Section("server").Key("OFFLINE_MODE").SetValue(strconv.FormatBool(form.OfflineMode)) if err := system_model.SetSettings(ctx, map[string]string{ setting.Config().Picture.DisableGravatar.DynKey(): strconv.FormatBool(form.DisableGravatar), setting.Config().Picture.EnableFederatedAvatar.DynKey(): strconv.FormatBool(form.EnableFederatedAvatar), @@ -441,17 +440,17 @@ func SubmitInstall(ctx *context.Context) { return } - cfg.Section("openid").Key("ENABLE_OPENID_SIGNIN").SetValue(fmt.Sprint(form.EnableOpenIDSignIn)) - cfg.Section("openid").Key("ENABLE_OPENID_SIGNUP").SetValue(fmt.Sprint(form.EnableOpenIDSignUp)) - cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(fmt.Sprint(form.DisableRegistration)) - cfg.Section("service").Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").SetValue(fmt.Sprint(form.AllowOnlyExternalRegistration)) - cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(fmt.Sprint(form.EnableCaptcha)) - cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(fmt.Sprint(form.RequireSignInView)) - cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(fmt.Sprint(form.DefaultKeepEmailPrivate)) - cfg.Section("service").Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").SetValue(fmt.Sprint(form.DefaultAllowCreateOrganization)) - cfg.Section("service").Key("DEFAULT_ENABLE_TIMETRACKING").SetValue(fmt.Sprint(form.DefaultEnableTimetracking)) - cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(fmt.Sprint(form.NoReplyAddress)) - cfg.Section("cron.update_checker").Key("ENABLED").SetValue(fmt.Sprint(form.EnableUpdateChecker)) + cfg.Section("openid").Key("ENABLE_OPENID_SIGNIN").SetValue(strconv.FormatBool(form.EnableOpenIDSignIn)) + cfg.Section("openid").Key("ENABLE_OPENID_SIGNUP").SetValue(strconv.FormatBool(form.EnableOpenIDSignUp)) + cfg.Section("service").Key("DISABLE_REGISTRATION").SetValue(strconv.FormatBool(form.DisableRegistration)) + cfg.Section("service").Key("ALLOW_ONLY_EXTERNAL_REGISTRATION").SetValue(strconv.FormatBool(form.AllowOnlyExternalRegistration)) + cfg.Section("service").Key("ENABLE_CAPTCHA").SetValue(strconv.FormatBool(form.EnableCaptcha)) + cfg.Section("service").Key("REQUIRE_SIGNIN_VIEW").SetValue(strconv.FormatBool(form.RequireSignInView)) + cfg.Section("service").Key("DEFAULT_KEEP_EMAIL_PRIVATE").SetValue(strconv.FormatBool(form.DefaultKeepEmailPrivate)) + cfg.Section("service").Key("DEFAULT_ALLOW_CREATE_ORGANIZATION").SetValue(strconv.FormatBool(form.DefaultAllowCreateOrganization)) + cfg.Section("service").Key("DEFAULT_ENABLE_TIMETRACKING").SetValue(strconv.FormatBool(form.DefaultEnableTimetracking)) + cfg.Section("service").Key("NO_REPLY_ADDRESS").SetValue(form.NoReplyAddress) + cfg.Section("cron.update_checker").Key("ENABLED").SetValue(strconv.FormatBool(form.EnableUpdateChecker)) cfg.Section("session").Key("PROVIDER").SetValue("file") diff --git a/routers/install/routes.go b/routers/install/routes.go index 7309a405d4..bc7a0eb48c 100644 --- a/routers/install/routes.go +++ b/routers/install/routes.go @@ -36,7 +36,7 @@ func Routes() *web.Router { func installNotFound(w http.ResponseWriter, req *http.Request) { w.Header().Add("Content-Type", "text/html; charset=utf-8") - w.Header().Add("Refresh", fmt.Sprintf("1; url=%s", setting.AppSubURL+"/")) + w.Header().Add("Refresh", "1; url="+setting.AppSubURL+"/") // do not use 30x status, because the "post-install" page needs to use 404/200 to detect if Gitea has been installed. // the fetch API could follow 30x requests to the page with 200 status. w.WriteHeader(http.StatusNotFound) diff --git a/routers/install/routes_test.go b/routers/install/routes_test.go index 2aa7f5d7b7..e8902ba3f1 100644 --- a/routers/install/routes_test.go +++ b/routers/install/routes_test.go @@ -4,6 +4,7 @@ package install import ( + "net/http" "net/http/httptest" "testing" @@ -17,20 +18,20 @@ func TestRoutes(t *testing.T) { assert.NotNil(t, r) w := httptest.NewRecorder() - req := httptest.NewRequest("GET", "/", nil) + req := httptest.NewRequest(http.MethodGet, "/", nil) r.ServeHTTP(w, req) - assert.EqualValues(t, 200, w.Code) + assert.Equal(t, 200, w.Code) assert.Contains(t, w.Body.String(), `class="page-content install"`) w = httptest.NewRecorder() - req = httptest.NewRequest("GET", "/no-such", nil) + req = httptest.NewRequest(http.MethodGet, "/no-such", nil) r.ServeHTTP(w, req) - assert.EqualValues(t, 404, w.Code) + assert.Equal(t, 404, w.Code) w = httptest.NewRecorder() - req = httptest.NewRequest("GET", "/assets/img/gitea.svg", nil) + req = httptest.NewRequest(http.MethodGet, "/assets/img/gitea.svg", nil) r.ServeHTTP(w, req) - assert.EqualValues(t, 200, w.Code) + assert.Equal(t, 200, w.Code) } func TestMain(m *testing.M) { diff --git a/routers/private/hook_post_receive_test.go b/routers/private/hook_post_receive_test.go index 34722f910d..ca721b16d1 100644 --- a/routers/private/hook_post_receive_test.go +++ b/routers/private/hook_post_receive_test.go @@ -43,7 +43,7 @@ func TestHandlePullRequestMerging(t *testing.T) { pr, err = issues_model.GetPullRequestByID(db.DefaultContext, pr.ID) assert.NoError(t, err) assert.True(t, pr.HasMerged) - assert.EqualValues(t, "01234567", pr.MergedCommitID) + assert.Equal(t, "01234567", pr.MergedCommitID) unittest.AssertNotExistsBean(t, &pull_model.AutoMerge{ID: autoMerge.ID}) } diff --git a/routers/private/hook_pre_receive.go b/routers/private/hook_pre_receive.go index 48fe591bbd..be9923c98f 100644 --- a/routers/private/hook_pre_receive.go +++ b/routers/private/hook_pre_receive.go @@ -311,13 +311,13 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r if isForcePush { log.Warn("Forbidden: User %d is not allowed to force-push to protected branch: %s in %-v", ctx.opts.UserID, branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ - UserMsg: fmt.Sprintf("Not allowed to force-push to protected branch %s", branchName), + UserMsg: "Not allowed to force-push to protected branch " + branchName, }) return } log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v", ctx.opts.UserID, branchName, repo) ctx.JSON(http.StatusForbidden, private.Response{ - UserMsg: fmt.Sprintf("Not allowed to push to protected branch %s", branchName), + UserMsg: "Not allowed to push to protected branch " + branchName, }) return } @@ -353,7 +353,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID string, r if !allowedMerge { log.Warn("Forbidden: User %d is not allowed to push to protected branch: %s in %-v and is not allowed to merge pr #%d", ctx.opts.UserID, branchName, repo, pr.Index) ctx.JSON(http.StatusForbidden, private.Response{ - UserMsg: fmt.Sprintf("Not allowed to push to protected branch %s", branchName), + UserMsg: "Not allowed to push to protected branch " + branchName, }) return } diff --git a/routers/private/hook_verification.go b/routers/private/hook_verification.go index 7c06cf8557..57d0964ead 100644 --- a/routers/private/hook_verification.go +++ b/routers/private/hook_verification.go @@ -6,7 +6,6 @@ package private import ( "bufio" "context" - "fmt" "io" "os" @@ -113,7 +112,7 @@ type errUnverifiedCommit struct { } func (e *errUnverifiedCommit) Error() string { - return fmt.Sprintf("Unverified commit: %s", e.sha) + return "Unverified commit: " + e.sha } func isErrUnverifiedCommit(err error) bool { diff --git a/routers/private/manager.go b/routers/private/manager.go index c712bbcf21..00e52d6511 100644 --- a/routers/private/manager.go +++ b/routers/private/manager.go @@ -180,7 +180,7 @@ func AddLogger(ctx *context.PrivateContext) { writerOption.Addr, _ = opts.Config["address"].(string) writerMode.WriterOption = writerOption default: - panic(fmt.Sprintf("invalid log writer mode: %s", writerType)) + panic("invalid log writer mode: " + writerType) } writer, err := log.NewEventWriter(opts.Writer, writerType, writerMode) if err != nil { diff --git a/routers/private/serv.go b/routers/private/serv.go index ecff3b7a53..37fbc0730c 100644 --- a/routers/private/serv.go +++ b/routers/private/serv.go @@ -286,7 +286,7 @@ func ServCommand(ctx *context.PrivateContext) { repo.IsPrivate || owner.Visibility.IsPrivate() || (user != nil && user.IsRestricted) || // user will be nil if the key is a deploykey - setting.Service.RequireSignInView) { + setting.Service.RequireSignInViewStrict) { if key.Type == asymkey_model.KeyTypeDeploy { if deployKey.Mode < mode { ctx.JSON(http.StatusUnauthorized, private.Response{ diff --git a/routers/web/admin/admin_test.go b/routers/web/admin/admin_test.go index 6c38f0b509..a568c7c5c8 100644 --- a/routers/web/admin/admin_test.go +++ b/routers/web/admin/admin_test.go @@ -69,7 +69,7 @@ func TestShadowPassword(t *testing.T) { } for _, k := range kases { - assert.EqualValues(t, k.Result, shadowPassword(k.Provider, k.CfgItem)) + assert.Equal(t, k.Result, shadowPassword(k.Provider, k.CfgItem)) } } @@ -79,7 +79,7 @@ func TestSelfCheckPost(t *testing.T) { ctx, resp := contexttest.MockContext(t, "GET http://host/sub/admin/self_check?location_origin=http://frontend") SelfCheckPost(ctx) - assert.EqualValues(t, http.StatusOK, resp.Code) + assert.Equal(t, http.StatusOK, resp.Code) data := struct { Problems []string `json:"problems"` diff --git a/routers/web/admin/applications.go b/routers/web/admin/applications.go index aec6349f21..79c3a08808 100644 --- a/routers/web/admin/applications.go +++ b/routers/web/admin/applications.go @@ -4,7 +4,6 @@ package admin import ( - "fmt" "net/http" "code.gitea.io/gitea/models/auth" @@ -23,8 +22,8 @@ var ( func newOAuth2CommonHandlers() *user_setting.OAuth2CommonHandlers { return &user_setting.OAuth2CommonHandlers{ OwnerID: 0, - BasePathList: fmt.Sprintf("%s/-/admin/applications", setting.AppSubURL), - BasePathEditPrefix: fmt.Sprintf("%s/-/admin/applications/oauth2", setting.AppSubURL), + BasePathList: setting.AppSubURL + "/-/admin/applications", + BasePathEditPrefix: setting.AppSubURL + "/-/admin/applications/oauth2", TplAppEdit: tplSettingsOauth2ApplicationEdit, } } diff --git a/routers/web/auth/oauth2_provider.go b/routers/web/auth/oauth2_provider.go index ff571fbf2c..1804b5b193 100644 --- a/routers/web/auth/oauth2_provider.go +++ b/routers/web/auth/oauth2_provider.go @@ -10,6 +10,7 @@ import ( "html/template" "net/http" "net/url" + "strconv" "strings" "code.gitea.io/gitea/models/auth" @@ -98,7 +99,7 @@ func InfoOAuth(ctx *context.Context) { } response := &userInfoResponse{ - Sub: fmt.Sprint(ctx.Doer.ID), + Sub: strconv.FormatInt(ctx.Doer.ID, 10), Name: ctx.Doer.DisplayName(), PreferredUsername: ctx.Doer.Name, Email: ctx.Doer.Email, @@ -171,7 +172,7 @@ func IntrospectOAuth(ctx *context.Context) { response.Scope = grant.Scope response.Issuer = setting.AppURL response.Audience = []string{app.ClientID} - response.Subject = fmt.Sprint(grant.UserID) + response.Subject = strconv.FormatInt(grant.UserID, 10) } if user, err := user_model.GetUserByID(ctx, grant.UserID); err == nil { response.Username = user.Name diff --git a/routers/web/auth/openid.go b/routers/web/auth/openid.go index c3415cccac..8c2d3276a8 100644 --- a/routers/web/auth/openid.go +++ b/routers/web/auth/openid.go @@ -4,7 +4,7 @@ package auth import ( - "fmt" + "errors" "net/http" "net/url" @@ -55,13 +55,13 @@ func allowedOpenIDURI(uri string) (err error) { } } // must match one of this or be refused - return fmt.Errorf("URI not allowed by whitelist") + return errors.New("URI not allowed by whitelist") } // A blacklist match expliclty forbids for _, pat := range setting.Service.OpenIDBlacklist { if pat.MatchString(uri) { - return fmt.Errorf("URI forbidden by blacklist") + return errors.New("URI forbidden by blacklist") } } @@ -99,7 +99,7 @@ func SignInOpenIDPost(ctx *context.Context) { url, err := openid.RedirectURL(id, redirectTo, setting.AppURL) if err != nil { log.Error("Error in OpenID redirect URL: %s, %v", redirectTo, err.Error()) - ctx.RenderWithErr(fmt.Sprintf("Unable to find OpenID provider in %s", redirectTo), tplSignInOpenID, &form) + ctx.RenderWithErr("Unable to find OpenID provider in "+redirectTo, tplSignInOpenID, &form) return } diff --git a/routers/web/auth/password.go b/routers/web/auth/password.go index 8dbde85fe6..537ad4b994 100644 --- a/routers/web/auth/password.go +++ b/routers/web/auth/password.go @@ -5,7 +5,6 @@ package auth import ( "errors" - "fmt" "net/http" "code.gitea.io/gitea/models/auth" @@ -108,14 +107,14 @@ func commonResetPassword(ctx *context.Context) (*user_model.User, *auth.TwoFacto } if len(code) == 0 { - ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true) + ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", setting.AppSubURL+"/user/forgot_password"), true) return nil, nil } // Fail early, don't frustrate the user u := user_model.VerifyUserTimeLimitCode(ctx, &user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeResetPassword}, code) if u == nil { - ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", fmt.Sprintf("%s/user/forgot_password", setting.AppSubURL)), true) + ctx.Flash.Error(ctx.Tr("auth.invalid_code_forgot_password", setting.AppSubURL+"/user/forgot_password"), true) return nil, nil } diff --git a/routers/web/base.go b/routers/web/base.go index a284dd0288..e43f36a97b 100644 --- a/routers/web/base.go +++ b/routers/web/base.go @@ -25,7 +25,7 @@ func avatarStorageHandler(storageSetting *setting.Storage, prefix string, objSto if storageSetting.ServeDirect() { return func(w http.ResponseWriter, req *http.Request) { - if req.Method != "GET" && req.Method != "HEAD" { + if req.Method != http.MethodGet && req.Method != http.MethodHead { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) return } @@ -56,7 +56,7 @@ func avatarStorageHandler(storageSetting *setting.Storage, prefix string, objSto } return func(w http.ResponseWriter, req *http.Request) { - if req.Method != "GET" && req.Method != "HEAD" { + if req.Method != http.MethodGet && req.Method != http.MethodHead { http.Error(w, http.StatusText(http.StatusMethodNotAllowed), http.StatusMethodNotAllowed) return } diff --git a/routers/web/devtest/devtest.go b/routers/web/devtest/devtest.go index 063ff42409..765931a730 100644 --- a/routers/web/devtest/devtest.go +++ b/routers/web/devtest/devtest.go @@ -4,6 +4,7 @@ package devtest import ( + "fmt" "html/template" "net/http" "path" @@ -128,6 +129,7 @@ func prepareMockDataBadgeCommitSign(ctx *context.Context) { func prepareMockDataBadgeActionsSvg(ctx *context.Context) { fontFamilyNames := strings.Split(badge.DefaultFontFamily, ",") selectedFontFamilyName := ctx.FormString("font", fontFamilyNames[0]) + selectedStyle := ctx.FormString("style", badge.DefaultStyle) var badges []badge.Badge badges = append(badges, badge.GenerateBadge("啊啊啊啊啊啊啊啊啊啊啊啊", "🌞🌞🌞🌞🌞", "green")) for r := rune(0); r < 256; r++ { @@ -141,7 +143,16 @@ func prepareMockDataBadgeActionsSvg(ctx *context.Context) { for i, b := range badges { b.IDPrefix = "devtest-" + strconv.FormatInt(int64(i), 10) + "-" b.FontFamily = selectedFontFamilyName - h, err := ctx.RenderToHTML("shared/actions/runner_badge", map[string]any{"Badge": b}) + var h template.HTML + var err error + switch selectedStyle { + case badge.StyleFlat: + h, err = ctx.RenderToHTML("shared/actions/runner_badge_flat", map[string]any{"Badge": b}) + case badge.StyleFlatSquare: + h, err = ctx.RenderToHTML("shared/actions/runner_badge_flat-square", map[string]any{"Badge": b}) + default: + err = fmt.Errorf("unknown badge style: %s", selectedStyle) + } if err != nil { ctx.ServerError("RenderToHTML", err) return @@ -151,6 +162,8 @@ func prepareMockDataBadgeActionsSvg(ctx *context.Context) { ctx.Data["BadgeSVGs"] = badgeSVGs ctx.Data["BadgeFontFamilyNames"] = fontFamilyNames ctx.Data["SelectedFontFamilyName"] = selectedFontFamilyName + ctx.Data["BadgeStyles"] = badge.GlobalVars().AllStyles + ctx.Data["SelectedStyle"] = selectedStyle } func prepareMockData(ctx *context.Context) { @@ -166,7 +179,7 @@ func prepareMockData(ctx *context.Context) { func TmplCommon(ctx *context.Context) { prepareMockData(ctx) - if ctx.Req.Method == "POST" { + if ctx.Req.Method == http.MethodPost { _ = ctx.Req.ParseForm() ctx.Flash.Info("form: "+ctx.Req.Method+" "+ctx.Req.RequestURI+""+ "Form: "+ctx.Req.Form.Encode()+""+ diff --git a/routers/web/devtest/mock_actions.go b/routers/web/devtest/mock_actions.go index 3ce75dfad2..023909aceb 100644 --- a/routers/web/devtest/mock_actions.go +++ b/routers/web/devtest/mock_actions.go @@ -4,9 +4,9 @@ package devtest import ( - "fmt" mathRand "math/rand/v2" "net/http" + "strconv" "strings" "time" @@ -38,8 +38,8 @@ func generateMockStepsLog(logCur actions.LogCursor) (stepsLog []*actions.ViewSte for i := 0; i < mockCount; i++ { logStr := mockedLogs[int(cur)%len(mockedLogs)] cur++ - logStr = strings.ReplaceAll(logStr, "{step}", fmt.Sprintf("%d", logCur.Step)) - logStr = strings.ReplaceAll(logStr, "{cursor}", fmt.Sprintf("%d", cur)) + logStr = strings.ReplaceAll(logStr, "{step}", strconv.Itoa(logCur.Step)) + logStr = strings.ReplaceAll(logStr, "{cursor}", strconv.FormatInt(cur, 10)) stepsLog = append(stepsLog, &actions.ViewStepLog{ Step: logCur.Step, Cursor: cur, diff --git a/routers/web/feed/branch.go b/routers/web/feed/branch.go index d3dae9503e..4a6fe9603d 100644 --- a/routers/web/feed/branch.go +++ b/routers/web/feed/branch.go @@ -4,7 +4,6 @@ package feed import ( - "fmt" "strings" "time" @@ -22,7 +21,7 @@ func ShowBranchFeed(ctx *context.Context, repo *repo.Repository, formatType stri return } - title := fmt.Sprintf("Latest commits for branch %s", ctx.Repo.BranchName) + title := "Latest commits for branch " + ctx.Repo.BranchName link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.RefTypeNameSubURL()} feed := &feeds.Feed{ diff --git a/routers/web/feed/file.go b/routers/web/feed/file.go index 407e4fa2d5..026c15c43a 100644 --- a/routers/web/feed/file.go +++ b/routers/web/feed/file.go @@ -4,7 +4,6 @@ package feed import ( - "fmt" "strings" "time" @@ -33,7 +32,7 @@ func ShowFileFeed(ctx *context.Context, repo *repo.Repository, formatType string return } - title := fmt.Sprintf("Latest commits for file %s", ctx.Repo.TreePath) + title := "Latest commits for file " + ctx.Repo.TreePath link := &feeds.Link{Href: repo.HTMLURL() + "/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)} diff --git a/routers/web/goget.go b/routers/web/goget.go index 79d5c2b207..67e0bee866 100644 --- a/routers/web/goget.go +++ b/routers/web/goget.go @@ -18,7 +18,7 @@ import ( ) func goGet(ctx *context.Context) { - if ctx.Req.Method != "GET" || len(ctx.Req.URL.RawQuery) < 8 || ctx.FormString("go-get") != "1" { + if ctx.Req.Method != http.MethodGet || len(ctx.Req.URL.RawQuery) < 8 || ctx.FormString("go-get") != "1" { return } diff --git a/routers/web/nodeinfo.go b/routers/web/nodeinfo.go index f1cc7bf530..47856bf98b 100644 --- a/routers/web/nodeinfo.go +++ b/routers/web/nodeinfo.go @@ -4,7 +4,6 @@ package web import ( - "fmt" "net/http" "code.gitea.io/gitea/modules/setting" @@ -24,7 +23,7 @@ type nodeInfoLink struct { func NodeInfoLinks(ctx *context.Context) { nodeinfolinks := &nodeInfoLinks{ Links: []nodeInfoLink{{ - fmt.Sprintf("%sapi/v1/nodeinfo", setting.AppURL), + setting.AppURL + "api/v1/nodeinfo", "http://nodeinfo.diaspora.software/ns/schema/2.1", }}, } diff --git a/routers/web/org/setting.go b/routers/web/org/setting.go index cb1c4213c9..a8a81e0ade 100644 --- a/routers/web/org/setting.go +++ b/routers/web/org/setting.go @@ -170,7 +170,7 @@ func SettingsDelete(ctx *context.Context) { ctx.Data["PageIsOrgSettings"] = true ctx.Data["PageIsSettingsDelete"] = true - if ctx.Req.Method == "POST" { + if ctx.Req.Method == http.MethodPost { if ctx.Org.Organization.Name != ctx.FormString("org_name") { ctx.Data["Err_OrgName"] = true ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_org_name"), tplSettingsDelete, nil) diff --git a/routers/web/repo/actions/actions.go b/routers/web/repo/actions/actions.go index d07d195713..5014ff52e3 100644 --- a/routers/web/repo/actions/actions.go +++ b/routers/web/repo/actions/actions.go @@ -6,6 +6,7 @@ package actions import ( "bytes" stdCtx "context" + "errors" "net/http" "slices" "strings" @@ -67,7 +68,11 @@ func List(ctx *context.Context) { ctx.Data["PageIsActions"] = true commit, err := ctx.Repo.GitRepo.GetBranchCommit(ctx.Repo.Repository.DefaultBranch) - if err != nil { + if errors.Is(err, util.ErrNotExist) { + ctx.Data["NotFoundPrompt"] = ctx.Tr("repo.branch.default_branch_not_exist", ctx.Repo.Repository.DefaultBranch) + ctx.NotFound(nil) + return + } else if err != nil { ctx.ServerError("GetBranchCommit", err) return } diff --git a/routers/web/repo/actions/badge.go b/routers/web/repo/actions/badge.go index e920ecaf58..d268a8df8a 100644 --- a/routers/web/repo/actions/badge.go +++ b/routers/web/repo/actions/badge.go @@ -5,35 +5,38 @@ package actions import ( "errors" - "fmt" "net/http" "path/filepath" "strings" actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/modules/badge" + "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/context" ) func GetWorkflowBadge(ctx *context.Context) { workflowFile := ctx.PathParam("workflow_name") - branch := ctx.Req.URL.Query().Get("branch") - if branch == "" { - branch = ctx.Repo.Repository.DefaultBranch - } - branchRef := fmt.Sprintf("refs/heads/%s", branch) - event := ctx.Req.URL.Query().Get("event") + branch := ctx.FormString("branch", ctx.Repo.Repository.DefaultBranch) + event := ctx.FormString("event") + style := ctx.FormString("style") - badge, err := getWorkflowBadge(ctx, workflowFile, branchRef, event) + branchRef := git.RefNameFromBranch(branch) + b, err := getWorkflowBadge(ctx, workflowFile, branchRef.String(), event) if err != nil { ctx.ServerError("GetWorkflowBadge", err) return } - ctx.Data["Badge"] = badge + ctx.Data["Badge"] = b ctx.RespHeader().Set("Content-Type", "image/svg+xml") - ctx.HTML(http.StatusOK, "shared/actions/runner_badge") + switch style { + case badge.StyleFlatSquare: + ctx.HTML(http.StatusOK, "shared/actions/runner_badge_flat-square") + default: // defaults to badge.StyleFlat + ctx.HTML(http.StatusOK, "shared/actions/runner_badge_flat") + } } func getWorkflowBadge(ctx *context.Context, workflowFile, branchName, event string) (badge.Badge, error) { @@ -48,7 +51,7 @@ func getWorkflowBadge(ctx *context.Context, workflowFile, branchName, event stri return badge.Badge{}, err } - color, ok := badge.StatusColorMap[run.Status] + color, ok := badge.GlobalVars().StatusColorMap[run.Status] if !ok { return badge.GenerateBadge(workflowName, "unknown status", badge.DefaultColor), nil } diff --git a/routers/web/repo/actions/view.go b/routers/web/repo/actions/view.go index eb6fc6ded6..2ec6389263 100644 --- a/routers/web/repo/actions/view.go +++ b/routers/web/repo/actions/view.go @@ -200,9 +200,9 @@ func ViewPost(ctx *context_module.Context) { } } - // TODO: "ComposeMetas" (usually for comment) is not quite right, but it is still the same as what template "RenderCommitMessage" does. + // TODO: "ComposeCommentMetas" (usually for comment) is not quite right, but it is still the same as what template "RenderCommitMessage" does. // need to be refactored together in the future - metas := ctx.Repo.Repository.ComposeMetas(ctx) + metas := ctx.Repo.Repository.ComposeCommentMetas(ctx) // the title for the "run" is from the commit message resp.State.Run.Title = run.Title @@ -508,7 +508,7 @@ func Cancel(ctx *context_module.Context) { return err } if n == 0 { - return fmt.Errorf("job has changed, try again") + return errors.New("job has changed, try again") } if n > 0 { updatedjobs = append(updatedjobs, job) diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go index 1d809ad8e9..8232f0cc04 100644 --- a/routers/web/repo/activity.go +++ b/routers/web/repo/activity.go @@ -8,6 +8,7 @@ import ( "time" activities_model "code.gitea.io/gitea/models/activities" + "code.gitea.io/gitea/models/git" "code.gitea.io/gitea/models/unit" "code.gitea.io/gitea/modules/templates" "code.gitea.io/gitea/services/context" @@ -52,12 +53,26 @@ func Activity(ctx *context.Context) { ctx.Data["DateUntil"] = timeUntil ctx.Data["PeriodText"] = ctx.Tr("repo.activity.period." + ctx.Data["Period"].(string)) + canReadCode := ctx.Repo.CanRead(unit.TypeCode) + if canReadCode { + // GetActivityStats needs to read the default branch to get some information + branchExist, _ := git.IsBranchExist(ctx, ctx.Repo.Repository.ID, ctx.Repo.Repository.DefaultBranch) + if !branchExist { + ctx.Data["NotFoundPrompt"] = ctx.Tr("repo.branch.default_branch_not_exist", ctx.Repo.Repository.DefaultBranch) + ctx.NotFound(nil) + return + } + } + var err error - if ctx.Data["Activity"], err = activities_model.GetActivityStats(ctx, ctx.Repo.Repository, timeFrom, + // TODO: refactor these arguments to a struct + ctx.Data["Activity"], err = activities_model.GetActivityStats(ctx, ctx.Repo.Repository, timeFrom, ctx.Repo.CanRead(unit.TypeReleases), ctx.Repo.CanRead(unit.TypeIssues), ctx.Repo.CanRead(unit.TypePullRequests), - ctx.Repo.CanRead(unit.TypeCode)); err != nil { + canReadCode, + ) + if err != nil { ctx.ServerError("GetActivityStats", err) return } diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go index ec50e1435e..690b830bc2 100644 --- a/routers/web/repo/cherry_pick.go +++ b/routers/web/repo/cherry_pick.go @@ -6,6 +6,7 @@ package repo import ( "bytes" "errors" + "net/http" "strings" git_model "code.gitea.io/gitea/models/git" @@ -59,7 +60,7 @@ func CherryPick(ctx *context.Context) { ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() - ctx.HTML(200, tplCherryPick) + ctx.HTML(http.StatusOK, tplCherryPick) } // CherryPickPost handles cherrypick POSTs @@ -88,7 +89,7 @@ func CherryPickPost(ctx *context.Context) { ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() if ctx.HasError() { - ctx.HTML(200, tplCherryPick) + ctx.HTML(http.StatusOK, tplCherryPick) return } diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go index 113622f872..c181aad050 100644 --- a/routers/web/repo/editor.go +++ b/routers/web/repo/editor.go @@ -668,7 +668,7 @@ func UploadFilePost(ctx *context.Context) { } if oldBranchName != branchName { - if _, err := ctx.Repo.GitRepo.GetBranch(branchName); err == nil { + if exist, err := git_model.IsBranchExist(ctx, ctx.Repo.Repository.ID, branchName); err == nil && exist { ctx.Data["Err_NewBranchName"] = true ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchName), tplUploadFile, &form) return @@ -875,12 +875,11 @@ func GetUniquePatchBranchName(ctx *context.Context) string { prefix := ctx.Doer.LowerName + "-patch-" for i := 1; i <= 1000; i++ { branchName := fmt.Sprintf("%s%d", prefix, i) - if _, err := ctx.Repo.GitRepo.GetBranch(branchName); err != nil { - if git.IsErrBranchNotExist(err) { - return branchName - } + if exist, err := git_model.IsBranchExist(ctx, ctx.Repo.Repository.ID, branchName); err != nil { log.Error("GetUniquePatchBranchName: %v", err) return "" + } else if !exist { + return branchName } } return "" diff --git a/routers/web/repo/editor_test.go b/routers/web/repo/editor_test.go index 566db31693..89bf8f309c 100644 --- a/routers/web/repo/editor_test.go +++ b/routers/web/repo/editor_test.go @@ -36,7 +36,7 @@ func TestCleanUploadName(t *testing.T) { "..a.dotty../.folder../.name...": "..a.dotty../.folder../.name...", } for k, v := range kases { - assert.EqualValues(t, cleanUploadFileName(k), v) + assert.Equal(t, cleanUploadFileName(k), v) } } diff --git a/routers/web/repo/githttp.go b/routers/web/repo/githttp.go index f93d7fc66a..f4ac9d769b 100644 --- a/routers/web/repo/githttp.go +++ b/routers/web/repo/githttp.go @@ -78,7 +78,7 @@ func httpBase(ctx *context.Context) *serviceHandler { strings.HasSuffix(ctx.Req.URL.Path, "git-upload-archive") { isPull = true } else { - isPull = ctx.Req.Method == "HEAD" || ctx.Req.Method == "GET" + isPull = ctx.Req.Method == http.MethodHead || ctx.Req.Method == http.MethodGet } var accessMode perm.AccessMode @@ -127,7 +127,7 @@ func httpBase(ctx *context.Context) *serviceHandler { // Only public pull don't need auth. isPublicPull := repoExist && !repo.IsPrivate && isPull var ( - askAuth = !isPublicPull || setting.Service.RequireSignInView + askAuth = !isPublicPull || setting.Service.RequireSignInViewStrict environ []string ) @@ -360,8 +360,8 @@ func setHeaderNoCache(ctx *context.Context) { func setHeaderCacheForever(ctx *context.Context) { now := time.Now().Unix() expires := now + 31536000 - ctx.Resp.Header().Set("Date", fmt.Sprintf("%d", now)) - ctx.Resp.Header().Set("Expires", fmt.Sprintf("%d", expires)) + ctx.Resp.Header().Set("Date", strconv.FormatInt(now, 10)) + ctx.Resp.Header().Set("Expires", strconv.FormatInt(expires, 10)) ctx.Resp.Header().Set("Cache-Control", "public, max-age=31536000") } @@ -394,7 +394,7 @@ func (h *serviceHandler) sendFile(ctx *context.Context, contentType, file string } ctx.Resp.Header().Set("Content-Type", contentType) - ctx.Resp.Header().Set("Content-Length", fmt.Sprintf("%d", fi.Size())) + ctx.Resp.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10)) // http.TimeFormat required a UTC time, refer to https://pkg.go.dev/net/http#TimeFormat ctx.Resp.Header().Set("Last-Modified", fi.ModTime().UTC().Format(http.TimeFormat)) http.ServeFile(ctx.Resp, ctx.Req, reqFile) diff --git a/routers/web/repo/githttp_test.go b/routers/web/repo/githttp_test.go index 5ba8de3d63..0164b11f66 100644 --- a/routers/web/repo/githttp_test.go +++ b/routers/web/repo/githttp_test.go @@ -37,6 +37,6 @@ func TestContainsParentDirectorySeparator(t *testing.T) { } for i := range tests { - assert.EqualValues(t, tests[i].b, containsParentDirectorySeparator(tests[i].v)) + assert.Equal(t, tests[i].b, containsParentDirectorySeparator(tests[i].v)) } } diff --git a/routers/web/repo/issue_label_test.go b/routers/web/repo/issue_label_test.go index 486c2e35a2..c3fba07034 100644 --- a/routers/web/repo/issue_label_test.go +++ b/routers/web/repo/issue_label_test.go @@ -38,7 +38,7 @@ func TestInitializeLabels(t *testing.T) { contexttest.LoadRepo(t, ctx, 2) web.SetForm(ctx, &forms.InitializeLabelsForm{TemplateName: "Default"}) InitializeLabels(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ RepoID: 2, Name: "enhancement", @@ -68,7 +68,7 @@ func TestRetrieveLabels(t *testing.T) { assert.True(t, ok) if assert.Len(t, labels, len(testCase.ExpectedLabelIDs)) { for i, label := range labels { - assert.EqualValues(t, testCase.ExpectedLabelIDs[i], label.ID) + assert.Equal(t, testCase.ExpectedLabelIDs[i], label.ID) } } } @@ -84,7 +84,7 @@ func TestNewLabel(t *testing.T) { Color: "#abcdef", }) NewLabel(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ Name: "newlabel", Color: "#abcdef", @@ -104,7 +104,7 @@ func TestUpdateLabel(t *testing.T) { IsArchived: true, }) UpdateLabel(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &issues_model.Label{ ID: 2, Name: "newnameforlabel", @@ -120,7 +120,7 @@ func TestDeleteLabel(t *testing.T) { contexttest.LoadRepo(t, ctx, 1) ctx.Req.Form.Set("id", "2") DeleteLabel(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) unittest.AssertNotExistsBean(t, &issues_model.Label{ID: 2}) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{LabelID: 2}) assert.EqualValues(t, ctx.Tr("repo.issues.label_deletion_success"), ctx.Flash.SuccessMsg) @@ -134,7 +134,7 @@ func TestUpdateIssueLabel_Clear(t *testing.T) { ctx.Req.Form.Set("issue_ids", "1,3") ctx.Req.Form.Set("action", "clear") UpdateIssueLabel(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 1}) unittest.AssertNotExistsBean(t, &issues_model.IssueLabel{IssueID: 3}) unittest.CheckConsistencyFor(t, &issues_model.Label{}) @@ -160,7 +160,7 @@ func TestUpdateIssueLabel_Toggle(t *testing.T) { ctx.Req.Form.Set("action", testCase.Action) ctx.Req.Form.Set("id", strconv.Itoa(int(testCase.LabelID))) UpdateIssueLabel(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) for _, issueID := range testCase.IssueIDs { if testCase.ExpectedAdd { unittest.AssertExistsAndLoadBean(t, &issues_model.IssueLabel{IssueID: issueID, LabelID: testCase.LabelID}) diff --git a/routers/web/repo/issue_list.go b/routers/web/repo/issue_list.go index 5dc9e8a6b5..d8ab653584 100644 --- a/routers/web/repo/issue_list.go +++ b/routers/web/repo/issue_list.go @@ -502,7 +502,7 @@ func issues(ctx *context.Context, milestoneID, projectID int64, isPullOption opt case "mentioned": mentionedID = ctx.Doer.ID case "assigned": - assigneeID = fmt.Sprint(ctx.Doer.ID) + assigneeID = strconv.FormatInt(ctx.Doer.ID, 10) case "review_requested": reviewRequestedID = ctx.Doer.ID case "reviewed_by": diff --git a/routers/web/repo/issue_new.go b/routers/web/repo/issue_new.go index 9f52396414..d8863961ff 100644 --- a/routers/web/repo/issue_new.go +++ b/routers/web/repo/issue_new.go @@ -223,11 +223,11 @@ func DeleteIssue(ctx *context.Context) { } if issue.IsPull { - ctx.Redirect(fmt.Sprintf("%s/pulls", ctx.Repo.Repository.Link()), http.StatusSeeOther) + ctx.Redirect(ctx.Repo.Repository.Link()+"/pulls", http.StatusSeeOther) return } - ctx.Redirect(fmt.Sprintf("%s/issues", ctx.Repo.Repository.Link()), http.StatusSeeOther) + ctx.Redirect(ctx.Repo.Repository.Link()+"/issues", http.StatusSeeOther) } func toSet[ItemType any, KeyType comparable](slice []ItemType, keyFunc func(ItemType) KeyType) container.Set[KeyType] { diff --git a/routers/web/repo/issue_view.go b/routers/web/repo/issue_view.go index b312f1260a..3ffcdfe676 100644 --- a/routers/web/repo/issue_view.go +++ b/routers/web/repo/issue_view.go @@ -278,7 +278,7 @@ func ViewIssue(ctx *context.Context) { extIssueUnit, err := ctx.Repo.Repository.GetUnit(ctx, unit.TypeExternalTracker) if err == nil && extIssueUnit != nil { if extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == markup.IssueNameStyleNumeric || extIssueUnit.ExternalTrackerConfig().ExternalTrackerStyle == "" { - metas := ctx.Repo.Repository.ComposeMetas(ctx) + metas := ctx.Repo.Repository.ComposeCommentMetas(ctx) metas["index"] = ctx.PathParam("index") res, err := vars.Expand(extIssueUnit.ExternalTrackerConfig().ExternalTrackerFormat, metas) if err != nil { diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go index 120b3469f6..ca346b7e6c 100644 --- a/routers/web/repo/patch.go +++ b/routers/web/repo/patch.go @@ -4,6 +4,7 @@ package repo import ( + "net/http" "strings" git_model "code.gitea.io/gitea/models/git" @@ -39,7 +40,7 @@ func NewDiffPatch(ctx *context.Context) { ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") ctx.Data["BranchLink"] = ctx.Repo.RepoLink + "/src/" + ctx.Repo.RefTypeNameSubURL() - ctx.HTML(200, tplPatchFile) + ctx.HTML(http.StatusOK, tplPatchFile) } // NewDiffPatchPost response for sending patch page @@ -62,7 +63,7 @@ func NewDiffPatchPost(ctx *context.Context) { ctx.Data["LineWrapExtensions"] = strings.Join(setting.Repository.Editor.LineWrapExtensions, ",") if ctx.HasError() { - ctx.HTML(200, tplPatchFile) + ctx.HTML(http.StatusOK, tplPatchFile) return } diff --git a/routers/web/repo/repo.go b/routers/web/repo/repo.go index 54b7448a89..e260ea36dd 100644 --- a/routers/web/repo/repo.go +++ b/routers/web/repo/repo.go @@ -305,11 +305,15 @@ func CreatePost(ctx *context.Context) { } func handleActionError(ctx *context.Context, err error) { - if errors.Is(err, user_model.ErrBlockedUser) { + switch { + case errors.Is(err, user_model.ErrBlockedUser): ctx.Flash.Error(ctx.Tr("repo.action.blocked_user")) - } else if errors.Is(err, util.ErrPermissionDenied) { + case repo_service.IsRepositoryLimitReached(err): + limit := err.(repo_service.LimitReachedError).Limit + ctx.Flash.Error(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit)) + case errors.Is(err, util.ErrPermissionDenied): ctx.HTTPError(http.StatusNotFound) - } else { + default: ctx.ServerError(fmt.Sprintf("Action (%s)", ctx.PathParam("action")), err) } } diff --git a/routers/web/repo/setting/protected_branch.go b/routers/web/repo/setting/protected_branch.go index 75de2ba1e7..f241242f02 100644 --- a/routers/web/repo/setting/protected_branch.go +++ b/routers/web/repo/setting/protected_branch.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" "time" @@ -110,7 +111,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) { var protectBranch *git_model.ProtectedBranch if f.RuleName == "" { ctx.Flash.Error(ctx.Tr("repo.settings.protected_branch_required_rule_name")) - ctx.Redirect(fmt.Sprintf("%s/settings/branches/edit", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/settings/branches/edit") return } @@ -283,32 +284,32 @@ func SettingsProtectedBranchPost(ctx *context.Context) { func DeleteProtectedBranchRulePost(ctx *context.Context) { ruleID := ctx.PathParamInt64("id") if ruleID <= 0 { - ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", strconv.FormatInt(ruleID, 10))) + ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/branches") return } rule, err := git_model.GetProtectedBranchRuleByID(ctx, ctx.Repo.Repository.ID, ruleID) if err != nil { - ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", strconv.FormatInt(ruleID, 10))) + ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/branches") return } if rule == nil { - ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", fmt.Sprintf("%d", ruleID))) - ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", strconv.FormatInt(ruleID, 10))) + ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/branches") return } if err := git_model.DeleteProtectedBranch(ctx, ctx.Repo.Repository, ruleID); err != nil { ctx.Flash.Error(ctx.Tr("repo.settings.remove_protected_branch_failed", rule.RuleName)) - ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/branches") return } ctx.Flash.Success(ctx.Tr("repo.settings.remove_protected_branch_success", rule.RuleName)) - ctx.JSONRedirect(fmt.Sprintf("%s/settings/branches", ctx.Repo.RepoLink)) + ctx.JSONRedirect(ctx.Repo.RepoLink + "/settings/branches") } func UpdateBranchProtectionPriories(ctx *context.Context) { @@ -332,7 +333,7 @@ func RenameBranchPost(ctx *context.Context) { if ctx.HasError() { ctx.Flash.Error(ctx.GetErrMsg()) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") return } @@ -341,13 +342,13 @@ func RenameBranchPost(ctx *context.Context) { switch { case repo_model.IsErrUserDoesNotHaveAccessToRepo(err): ctx.Flash.Error(ctx.Tr("repo.branch.rename_default_or_protected_branch_error")) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") case git_model.IsErrBranchAlreadyExists(err): ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", form.To)) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") case errors.Is(err, git_model.ErrBranchIsProtected): ctx.Flash.Error(ctx.Tr("repo.branch.rename_protected_branch_failed")) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") default: ctx.ServerError("RenameBranch", err) } @@ -356,16 +357,16 @@ func RenameBranchPost(ctx *context.Context) { if msg == "target_exist" { ctx.Flash.Error(ctx.Tr("repo.settings.rename_branch_failed_exist", form.To)) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") return } if msg == "from_not_exist" { ctx.Flash.Error(ctx.Tr("repo.settings.rename_branch_failed_not_exist", form.From)) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") return } ctx.Flash.Success(ctx.Tr("repo.settings.rename_branch_success", form.From, form.To)) - ctx.Redirect(fmt.Sprintf("%s/branches", ctx.Repo.RepoLink)) + ctx.Redirect(ctx.Repo.RepoLink + "/branches") } diff --git a/routers/web/repo/setting/setting.go b/routers/web/repo/setting/setting.go index a0edb1e11a..380fec9d4a 100644 --- a/routers/web/repo/setting/setting.go +++ b/routers/web/repo/setting/setting.go @@ -6,7 +6,6 @@ package setting import ( "errors" - "fmt" "net/http" "strings" "time" @@ -474,7 +473,7 @@ func handleSettingsPostPushMirrorAdd(ctx *context.Context) { m := &repo_model.PushMirror{ RepoID: repo.ID, Repo: repo, - RemoteName: fmt.Sprintf("remote_mirror_%s", remoteSuffix), + RemoteName: "remote_mirror_" + remoteSuffix, SyncOnCommit: form.PushMirrorSyncOnCommit, Interval: interval, RemoteAddress: remoteAddress, @@ -848,6 +847,9 @@ func handleSettingsPostTransfer(ctx *context.Context) { ctx.RenderWithErr(ctx.Tr("repo.settings.new_owner_has_same_repo"), tplSettingsOptions, nil) } else if repo_model.IsErrRepoTransferInProgress(err) { ctx.RenderWithErr(ctx.Tr("repo.settings.transfer_in_progress"), tplSettingsOptions, nil) + } else if repo_service.IsRepositoryLimitReached(err) { + limit := err.(repo_service.LimitReachedError).Limit + ctx.RenderWithErr(ctx.TrN(limit, "repo.form.reach_limit_of_creation_1", "repo.form.reach_limit_of_creation_n", limit), tplSettingsOptions, nil) } else if errors.Is(err, user_model.ErrBlockedUser) { ctx.RenderWithErr(ctx.Tr("repo.settings.transfer.blocked_user"), tplSettingsOptions, nil) } else { diff --git a/routers/web/repo/setting/settings_test.go b/routers/web/repo/setting/settings_test.go index ad33dac514..ba6b0d1efc 100644 --- a/routers/web/repo/setting/settings_test.go +++ b/routers/web/repo/setting/settings_test.go @@ -54,7 +54,7 @@ func TestAddReadOnlyDeployKey(t *testing.T) { } web.SetForm(ctx, &addKeyForm) DeployKeysPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ Name: addKeyForm.Title, @@ -84,7 +84,7 @@ func TestAddReadWriteOnlyDeployKey(t *testing.T) { } web.SetForm(ctx, &addKeyForm) DeployKeysPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ Name: addKeyForm.Title, @@ -121,7 +121,7 @@ func TestCollaborationPost(t *testing.T) { CollaborationPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) exists, err := repo_model.IsCollaborator(ctx, re.ID, 4) assert.NoError(t, err) @@ -147,7 +147,7 @@ func TestCollaborationPost_InactiveUser(t *testing.T) { CollaborationPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } @@ -179,7 +179,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) { CollaborationPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) exists, err := repo_model.IsCollaborator(ctx, re.ID, 4) assert.NoError(t, err) @@ -188,7 +188,7 @@ func TestCollaborationPost_AddCollaboratorTwice(t *testing.T) { // Try adding the same collaborator again CollaborationPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } @@ -210,7 +210,7 @@ func TestCollaborationPost_NonExistentUser(t *testing.T) { CollaborationPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } @@ -250,7 +250,7 @@ func TestAddTeamPost(t *testing.T) { AddTeamPost(ctx) assert.True(t, repo_service.HasRepository(db.DefaultContext, team, re.ID)) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.Empty(t, ctx.Flash.ErrorMsg) } @@ -290,7 +290,7 @@ func TestAddTeamPost_NotAllowed(t *testing.T) { AddTeamPost(ctx) assert.False(t, repo_service.HasRepository(db.DefaultContext, team, re.ID)) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } @@ -331,7 +331,7 @@ func TestAddTeamPost_AddTeamTwice(t *testing.T) { AddTeamPost(ctx) assert.True(t, repo_service.HasRepository(db.DefaultContext, team, re.ID)) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } @@ -364,7 +364,7 @@ func TestAddTeamPost_NonExistentTeam(t *testing.T) { ctx.Repo = repo AddTeamPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.NotEmpty(t, ctx.Flash.ErrorMsg) } diff --git a/routers/web/repo/treelist.go b/routers/web/repo/treelist.go index ab74741e61..9c5ec8f206 100644 --- a/routers/web/repo/treelist.go +++ b/routers/web/repo/treelist.go @@ -8,6 +8,7 @@ import ( pull_model "code.gitea.io/gitea/models/pull" "code.gitea.io/gitea/modules/base" + "code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/services/gitdiff" @@ -87,10 +88,11 @@ func transformDiffTreeForUI(diffTree *gitdiff.DiffTree, filesViewedState map[str } func TreeViewNodes(ctx *context.Context) { - results, err := files_service.GetTreeViewNodes(ctx, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path")) + renderedIconPool := fileicon.NewRenderedIconPool() + results, err := files_service.GetTreeViewNodes(ctx, renderedIconPool, ctx.Repo.Commit, ctx.Repo.TreePath, ctx.FormString("sub_path")) if err != nil { ctx.ServerError("GetTreeViewNodes", err) return } - ctx.JSON(http.StatusOK, map[string]any{"fileTreeNodes": results}) + ctx.JSON(http.StatusOK, map[string]any{"fileTreeNodes": results, "renderedIconPool": renderedIconPool.IconSVGs}) } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index 6ed5801d10..77240f0431 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -29,6 +29,7 @@ import ( user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/charset" + "code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/lfs" "code.gitea.io/gitea/modules/log" @@ -252,6 +253,16 @@ func LastCommit(ctx *context.Context) { ctx.HTML(http.StatusOK, tplRepoViewList) } +func prepareDirectoryFileIcons(ctx *context.Context, files []git.CommitInfo) { + renderedIconPool := fileicon.NewRenderedIconPool() + fileIcons := map[string]template.HTML{} + for _, f := range files { + fileIcons[f.Entry.Name()] = fileicon.RenderEntryIcon(renderedIconPool, f.Entry) + } + ctx.Data["FileIcons"] = fileIcons + ctx.Data["FileIconPoolHTML"] = renderedIconPool.RenderToHTML() +} + func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entries { tree, err := ctx.Repo.Commit.SubTree(ctx.Repo.TreePath) if err != nil { @@ -293,6 +304,7 @@ func renderDirectoryFiles(ctx *context.Context, timeout time.Duration) git.Entri return nil } ctx.Data["Files"] = files + prepareDirectoryFileIcons(ctx, files) for _, f := range files { if f.Commit == nil { ctx.Data["HasFilesWithoutLatestCommit"] = true diff --git a/routers/web/repo/view_file.go b/routers/web/repo/view_file.go index 4ce7a8e3a4..12083a1ced 100644 --- a/routers/web/repo/view_file.go +++ b/routers/web/repo/view_file.go @@ -30,32 +30,31 @@ import ( "github.com/nektos/act/pkg/model" ) +func prepareLatestCommitInfo(ctx *context.Context) bool { + commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath) + if err != nil { + ctx.ServerError("GetCommitByPath", err) + return false + } + + return loadLatestCommitData(ctx, commit) +} + func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["IsViewFile"] = true ctx.Data["HideRepoInfo"] = true - blob := entry.Blob() - buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob) - if err != nil { - ctx.ServerError("getFileReader", err) + + if !prepareLatestCommitInfo(ctx) { return } - defer dataRc.Close() + + blob := entry.Blob() ctx.Data["Title"] = ctx.Tr("repo.file.title", ctx.Repo.Repository.Name+"/"+path.Base(ctx.Repo.TreePath), ctx.Repo.RefFullName.ShortName()) ctx.Data["FileIsSymlink"] = entry.IsLink() ctx.Data["FileName"] = blob.Name() ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) - commit, err := ctx.Repo.Commit.GetCommitByPath(ctx.Repo.TreePath) - if err != nil { - ctx.ServerError("GetCommitByPath", err) - return - } - - if !loadLatestCommitData(ctx, commit) { - return - } - if ctx.Repo.TreePath == ".editorconfig" { _, editorconfigWarning, editorconfigErr := ctx.Repo.GetEditorconfig(ctx.Repo.Commit) if editorconfigWarning != nil { @@ -90,6 +89,15 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { isDisplayingSource := ctx.FormString("display") == "source" isDisplayingRendered := !isDisplayingSource + // Don't call any other repository functions depends on git.Repository until the dataRc closed to + // avoid create unnecessary temporary cat file. + buf, dataRc, fInfo, err := getFileReader(ctx, ctx.Repo.Repository.ID, blob) + if err != nil { + ctx.ServerError("getFileReader", err) + return + } + defer dataRc.Close() + if fInfo.isLFSFile { ctx.Data["RawFileLink"] = ctx.Repo.RepoLink + "/media/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath) } @@ -168,7 +176,7 @@ func prepareToRenderFile(ctx *context.Context, entry *git.TreeEntry) { if markupType != "" && !shouldRenderSource { ctx.Data["IsMarkup"] = true ctx.Data["MarkupType"] = markupType - metas := ctx.Repo.Repository.ComposeDocumentMetas(ctx) + metas := ctx.Repo.Repository.ComposeRepoFileMetas(ctx) metas["RefTypeNameSubURL"] = ctx.Repo.RefTypeNameSubURL() rctx := renderhelper.NewRenderContextRepoFile(ctx, ctx.Repo.Repository, renderhelper.RepoFileOptions{ CurrentRefPath: ctx.Repo.RefTypeNameSubURL(), diff --git a/routers/web/repo/view_home.go b/routers/web/repo/view_home.go index d538406035..3b053821ee 100644 --- a/routers/web/repo/view_home.go +++ b/routers/web/repo/view_home.go @@ -20,6 +20,8 @@ import ( unit_model "code.gitea.io/gitea/models/unit" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" + giturl "code.gitea.io/gitea/modules/git/url" + "code.gitea.io/gitea/modules/httplib" "code.gitea.io/gitea/modules/log" repo_module "code.gitea.io/gitea/modules/repository" "code.gitea.io/gitea/modules/setting" @@ -76,7 +78,7 @@ func prepareOpenWithEditorApps(ctx *context.Context) { schema, _, _ := strings.Cut(app.OpenURL, ":") var iconHTML template.HTML if schema == "vscode" || schema == "vscodium" || schema == "jetbrains" { - iconHTML = svg.RenderHTML(fmt.Sprintf("gitea-%s", schema), 16) + iconHTML = svg.RenderHTML("gitea-"+schema, 16) } else { iconHTML = svg.RenderHTML("gitea-git", 16) // TODO: it could support user's customized icon in the future } @@ -269,7 +271,7 @@ func handleRepoEmptyOrBroken(ctx *context.Context) { } else if reallyEmpty { showEmpty = true // the repo is really empty updateContextRepoEmptyAndStatus(ctx, true, repo_model.RepositoryReady) - } else if branches, _, _ := ctx.Repo.GitRepo.GetBranches(0, 1); len(branches) == 0 { + } else if branches, _, _ := ctx.Repo.GitRepo.GetBranchNames(0, 1); len(branches) == 0 { showEmpty = true // it is not really empty, but there is no branch // at the moment, other repo units like "actions" are not able to handle such case, // so we just mark the repo as empty to prevent from displaying these units. @@ -302,8 +304,33 @@ func handleRepoEmptyOrBroken(ctx *context.Context) { ctx.Redirect(link) } +func handleRepoViewSubmodule(ctx *context.Context, submodule *git.SubModule) { + submoduleRepoURL, err := giturl.ParseRepositoryURL(ctx, submodule.URL) + if err != nil { + HandleGitError(ctx, "prepareToRenderDirOrFile: ParseRepositoryURL", err) + return + } + submoduleURL := giturl.MakeRepositoryWebLink(submoduleRepoURL) + if httplib.IsCurrentGiteaSiteURL(ctx, submoduleURL) { + ctx.RedirectToCurrentSite(submoduleURL) + } else { + // don't auto-redirect to external URL, to avoid open redirect or phishing + ctx.Data["NotFoundPrompt"] = submoduleURL + ctx.NotFound(nil) + } +} + func prepareToRenderDirOrFile(entry *git.TreeEntry) func(ctx *context.Context) { return func(ctx *context.Context) { + if entry.IsSubModule() { + submodule, err := ctx.Repo.Commit.GetSubModule(entry.Name()) + if err != nil { + HandleGitError(ctx, "prepareToRenderDirOrFile: GetSubModule", err) + return + } + handleRepoViewSubmodule(ctx, submodule) + return + } if entry.IsDir() { prepareToRenderDirectory(ctx) } else { @@ -343,12 +370,25 @@ func prepareHomeTreeSideBarSwitch(ctx *context.Context) { ctx.Data["UserSettingCodeViewShowFileTree"] = showFileTree } +func redirectSrcToRaw(ctx *context.Context) bool { + // GitHub redirects a tree path with "?raw=1" to the raw path + // It is useful to embed some raw contents into markdown files, + // then viewing the markdown in "src" path could embed the raw content correctly. + if ctx.Repo.TreePath != "" && ctx.FormBool("raw") { + ctx.Redirect(ctx.Repo.RepoLink + "/raw/" + ctx.Repo.RefTypeNameSubURL() + "/" + util.PathEscapeSegments(ctx.Repo.TreePath)) + return true + } + return false +} + // Home render repository home page func Home(ctx *context.Context) { if handleRepoHomeFeed(ctx) { return } - + if redirectSrcToRaw(ctx) { + return + } // Check whether the repo is viewable: not in migration, and the code unit should be enabled // Ideally the "feed" logic should be after this, but old code did so, so keep it as-is. checkHomeCodeViewable(ctx) diff --git a/routers/web/repo/view_home_test.go b/routers/web/repo/view_home_test.go new file mode 100644 index 0000000000..6264dba71c --- /dev/null +++ b/routers/web/repo/view_home_test.go @@ -0,0 +1,32 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package repo + +import ( + "net/http" + "testing" + + "code.gitea.io/gitea/models/unittest" + git_module "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/services/contexttest" + + "github.com/stretchr/testify/assert" +) + +func TestViewHomeSubmoduleRedirect(t *testing.T) { + unittest.PrepareTestEnv(t) + + ctx, _ := contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule") + submodule := &git_module.SubModule{Path: "test-submodule", URL: setting.AppURL + "user2/repo-other.git"} + handleRepoViewSubmodule(ctx, submodule) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, "/user2/repo-other", ctx.Resp.Header().Get("Location")) + + ctx, _ = contexttest.MockContext(t, "/user2/repo1/src/branch/master/test-submodule") + submodule = &git_module.SubModule{Path: "test-submodule", URL: "https://other/user2/repo-other.git"} + handleRepoViewSubmodule(ctx, submodule) + // do not auto-redirect for external URLs, to avoid open redirect or phishing + assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus()) +} diff --git a/routers/web/repo/view_readme.go b/routers/web/repo/view_readme.go index 48befe47f8..606ee7ff79 100644 --- a/routers/web/repo/view_readme.go +++ b/routers/web/repo/view_readme.go @@ -69,7 +69,7 @@ func findReadmeFileInEntries(ctx *context.Context, entries []*git.TreeEntry, try if readmeFiles[i] == nil || base.NaturalSortLess(readmeFiles[i].Name(), entry.Blob().Name()) { if entry.IsLink() { target, err := entry.FollowLinks() - if err != nil && !git.IsErrBadLink(err) { + if err != nil && !git.IsErrSymlinkUnresolved(err) { return "", nil, err } else if target != nil && (target.IsExecutable() || target.IsRegular()) { readmeFiles[i] = entry diff --git a/routers/web/repo/wiki.go b/routers/web/repo/wiki.go index 20c8c2b406..d70760bc36 100644 --- a/routers/web/repo/wiki.go +++ b/routers/web/repo/wiki.go @@ -7,7 +7,6 @@ package repo import ( "bytes" gocontext "context" - "fmt" "io" "net/http" "net/url" @@ -581,7 +580,7 @@ func Wiki(ctx *context.Context) { wikiPath := entry.Name() if markup.DetectMarkupTypeByFileName(wikiPath) != markdown.MarkupName { ext := strings.ToUpper(filepath.Ext(wikiPath)) - ctx.Data["FormatWarning"] = fmt.Sprintf("%s rendering is not supported at the moment. Rendered as Markdown.", ext) + ctx.Data["FormatWarning"] = ext + " rendering is not supported at the moment. Rendered as Markdown." } // Get last change information. lastCommit, err := wikiRepo.GetCommitByPath(wikiPath) diff --git a/routers/web/repo/wiki_test.go b/routers/web/repo/wiki_test.go index e44cf46ba8..b5dfa9f856 100644 --- a/routers/web/repo/wiki_test.go +++ b/routers/web/repo/wiki_test.go @@ -71,7 +71,7 @@ func assertPagesMetas(t *testing.T, expectedNames []string, metas any) { require.Len(t, pageMetas, len(expectedNames)) for i, pageMeta := range pageMetas { - assert.EqualValues(t, expectedNames[i], pageMeta.Name) + assert.Equal(t, expectedNames[i], pageMeta.Name) } } @@ -82,7 +82,7 @@ func TestWiki(t *testing.T) { ctx.SetPathParam("*", "Home") contexttest.LoadRepo(t, ctx, 1) Wiki(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, "Home", ctx.Data["Title"]) assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"]) @@ -90,7 +90,7 @@ func TestWiki(t *testing.T) { ctx.SetPathParam("*", "jpeg.jpg") contexttest.LoadRepo(t, ctx, 1) Wiki(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assert.Equal(t, "/user2/repo1/wiki/raw/jpeg.jpg", ctx.Resp.Header().Get("Location")) } @@ -100,7 +100,7 @@ func TestWikiPages(t *testing.T) { ctx, _ := contexttest.MockContext(t, "user2/repo1/wiki/?action=_pages") contexttest.LoadRepo(t, ctx, 1) WikiPages(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assertPagesMetas(t, []string{"Home", "Page With Image", "Page With Spaced Name", "Unescaped File"}, ctx.Data["Pages"]) } @@ -111,7 +111,7 @@ func TestNewWiki(t *testing.T) { contexttest.LoadUser(t, ctx, 2) contexttest.LoadRepo(t, ctx, 1) NewWiki(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, ctx.Tr("repo.wiki.new_page"), ctx.Data["Title"]) } @@ -131,7 +131,7 @@ func TestNewWikiPost(t *testing.T) { Message: message, }) NewWikiPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)) assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))) } @@ -149,7 +149,7 @@ func TestNewWikiPost_ReservedName(t *testing.T) { Message: message, }) NewWikiPost(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, ctx.Tr("repo.wiki.reserved_page", "_edit"), ctx.Flash.ErrorMsg) assertWikiNotExists(t, ctx.Repo.Repository, "_edit") } @@ -162,7 +162,7 @@ func TestEditWiki(t *testing.T) { contexttest.LoadUser(t, ctx, 2) contexttest.LoadRepo(t, ctx, 1) EditWiki(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, "Home", ctx.Data["Title"]) assert.Equal(t, wikiContent(t, ctx.Repo.Repository, "Home"), ctx.Data["content"]) @@ -171,7 +171,7 @@ func TestEditWiki(t *testing.T) { contexttest.LoadUser(t, ctx, 2) contexttest.LoadRepo(t, ctx, 1) EditWiki(ctx) - assert.EqualValues(t, http.StatusForbidden, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusForbidden, ctx.Resp.WrittenStatus()) } func TestEditWikiPost(t *testing.T) { @@ -190,7 +190,7 @@ func TestEditWikiPost(t *testing.T) { Message: message, }) EditWikiPost(ctx) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) assertWikiExists(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title)) assert.Equal(t, content, wikiContent(t, ctx.Repo.Repository, wiki_service.UserTitleToWebPath("", title))) if title != "Home" { @@ -206,7 +206,7 @@ func TestDeleteWikiPagePost(t *testing.T) { contexttest.LoadUser(t, ctx, 2) contexttest.LoadRepo(t, ctx, 1) DeleteWikiPagePost(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assertWikiNotExists(t, ctx.Repo.Repository, "Home") } @@ -228,10 +228,10 @@ func TestWikiRaw(t *testing.T) { contexttest.LoadRepo(t, ctx, 1) WikiRaw(ctx) if filetype == "" { - assert.EqualValues(t, http.StatusNotFound, ctx.Resp.WrittenStatus(), "filepath: %s", filepath) + assert.Equal(t, http.StatusNotFound, ctx.Resp.WrittenStatus(), "filepath: %s", filepath) } else { - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus(), "filepath: %s", filepath) - assert.EqualValues(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus(), "filepath: %s", filepath) + assert.Equal(t, filetype, ctx.Resp.Header().Get("Content-Type"), "filepath: %s", filepath) } } } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index f90d9df897..77f9cb8cca 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -699,7 +699,7 @@ func ShowGPGKeys(ctx *context.Context) { headers := make(map[string]string) if len(failedEntitiesID) > 0 { // If some key need re-import to be exported - headers["Note"] = fmt.Sprintf("The keys with the following IDs couldn't be exported and need to be reuploaded %s", strings.Join(failedEntitiesID, ", ")) + headers["Note"] = "The keys with the following IDs couldn't be exported and need to be reuploaded " + strings.Join(failedEntitiesID, ", ") } else if len(entities) == 0 { headers["Note"] = "This user hasn't uploaded any GPG keys." } diff --git a/routers/web/user/home_test.go b/routers/web/user/home_test.go index b2c8ad98ba..2a8a8812e3 100644 --- a/routers/web/user/home_test.go +++ b/routers/web/user/home_test.go @@ -37,15 +37,15 @@ func TestArchivedIssues(t *testing.T) { NumIssues[repo.ID] = repo.NumIssues } assert.False(t, IsArchived[50]) - assert.EqualValues(t, 1, NumIssues[50]) + assert.Equal(t, 1, NumIssues[50]) assert.True(t, IsArchived[51]) - assert.EqualValues(t, 1, NumIssues[51]) + assert.Equal(t, 1, NumIssues[51]) // Act Issues(ctx) // Assert: One Issue (ID 30) from one Repo (ID 50) is retrieved, while nothing from archived Repo 51 is retrieved - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.Len(t, ctx.Data["Issues"], 1) } @@ -58,7 +58,7 @@ func TestIssues(t *testing.T) { contexttest.LoadUser(t, ctx, 2) ctx.Req.Form.Set("state", "closed") Issues(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, true, ctx.Data["IsShowClosed"]) assert.Len(t, ctx.Data["Issues"], 1) @@ -72,7 +72,7 @@ func TestPulls(t *testing.T) { contexttest.LoadUser(t, ctx, 2) ctx.Req.Form.Set("state", "open") Pulls(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.Len(t, ctx.Data["Issues"], 5) } @@ -87,7 +87,7 @@ func TestMilestones(t *testing.T) { ctx.Req.Form.Set("state", "closed") ctx.Req.Form.Set("sort", "furthestduedate") Milestones(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, map[int64]int64{1: 1}, ctx.Data["Counts"]) assert.EqualValues(t, true, ctx.Data["IsShowClosed"]) assert.EqualValues(t, "furthestduedate", ctx.Data["SortType"]) @@ -107,7 +107,7 @@ func TestMilestonesForSpecificRepo(t *testing.T) { ctx.Req.Form.Set("state", "closed") ctx.Req.Form.Set("sort", "furthestduedate") Milestones(ctx) - assert.EqualValues(t, http.StatusOK, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusOK, ctx.Resp.WrittenStatus()) assert.EqualValues(t, map[int64]int64{1: 1}, ctx.Data["Counts"]) assert.EqualValues(t, true, ctx.Data["IsShowClosed"]) assert.EqualValues(t, "furthestduedate", ctx.Data["SortType"]) diff --git a/routers/web/user/setting/account.go b/routers/web/user/setting/account.go index 94577832a9..b124d5e1de 100644 --- a/routers/web/user/setting/account.go +++ b/routers/web/user/setting/account.go @@ -6,7 +6,6 @@ package setting import ( "errors" - "fmt" "net/http" "time" @@ -37,7 +36,7 @@ const ( // Account renders change user's password, user's email and user suicide page func Account(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials, setting.UserFeatureDeletion) && !setting.Service.EnableNotifyMail { - ctx.NotFound(fmt.Errorf("account setting are not allowed to be changed")) + ctx.NotFound(errors.New("account setting are not allowed to be changed")) return } @@ -54,7 +53,7 @@ func Account(ctx *context.Context) { // AccountPost response for change user's password func AccountPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound(fmt.Errorf("password setting is not allowed to be changed")) + ctx.NotFound(errors.New("password setting is not allowed to be changed")) return } @@ -105,7 +104,7 @@ func AccountPost(ctx *context.Context) { // EmailPost response for change user's email func EmailPost(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound(fmt.Errorf("emails are not allowed to be changed")) + ctx.NotFound(errors.New("emails are not allowed to be changed")) return } @@ -239,7 +238,7 @@ func EmailPost(ctx *context.Context) { // DeleteEmail response for delete user's email func DeleteEmail(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageCredentials) { - ctx.NotFound(fmt.Errorf("emails are not allowed to be changed")) + ctx.NotFound(errors.New("emails are not allowed to be changed")) return } email, err := user_model.GetEmailAddressByID(ctx, ctx.Doer.ID, ctx.FormInt64("id")) diff --git a/routers/web/user/setting/account_test.go b/routers/web/user/setting/account_test.go index 13caa33771..9b8cffc868 100644 --- a/routers/web/user/setting/account_test.go +++ b/routers/web/user/setting/account_test.go @@ -95,7 +95,7 @@ func TestChangePassword(t *testing.T) { AccountPost(ctx) assert.Contains(t, ctx.Flash.ErrorMsg, req.Message) - assert.EqualValues(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) + assert.Equal(t, http.StatusSeeOther, ctx.Resp.WrittenStatus()) }) } } diff --git a/routers/web/user/setting/applications.go b/routers/web/user/setting/applications.go index 1f6c97a5cc..c3d8b93adb 100644 --- a/routers/web/user/setting/applications.go +++ b/routers/web/user/setting/applications.go @@ -54,7 +54,7 @@ func ApplicationsPost(ctx *context.Context) { ctx.ServerError("GetScope", err) return } - if scope == "" || scope == auth_model.AccessTokenScopePublicOnly { + if !scope.HasPermissionScope() { ctx.Flash.Error(ctx.Tr("settings.at_least_one_permission"), true) } diff --git a/routers/web/user/setting/keys.go b/routers/web/user/setting/keys.go index 17e32f5403..6b5a7a2e2a 100644 --- a/routers/web/user/setting/keys.go +++ b/routers/web/user/setting/keys.go @@ -5,7 +5,7 @@ package setting import ( - "fmt" + "errors" "net/http" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -26,7 +26,7 @@ const ( // Keys render user's SSH/GPG public keys page func Keys(ctx *context.Context) { if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys, setting.UserFeatureManageGPGKeys) { - ctx.NotFound(fmt.Errorf("keys setting is not allowed to be changed")) + ctx.NotFound(errors.New("keys setting is not allowed to be changed")) return } @@ -87,7 +87,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "gpg": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound(fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.NotFound(errors.New("gpg keys setting is not allowed to be visited")) return } @@ -168,7 +168,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(errors.New("ssh keys setting is not allowed to be visited")) return } @@ -212,7 +212,7 @@ func KeysPost(ctx *context.Context) { ctx.Redirect(setting.AppSubURL + "/user/settings/keys") case "verify_ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(errors.New("ssh keys setting is not allowed to be visited")) return } @@ -249,7 +249,7 @@ func DeleteKey(ctx *context.Context) { switch ctx.FormString("type") { case "gpg": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageGPGKeys) { - ctx.NotFound(fmt.Errorf("gpg keys setting is not allowed to be visited")) + ctx.NotFound(errors.New("gpg keys setting is not allowed to be visited")) return } if err := asymkey_model.DeleteGPGKey(ctx, ctx.Doer, ctx.FormInt64("id")); err != nil { @@ -259,7 +259,7 @@ func DeleteKey(ctx *context.Context) { } case "ssh": if user_model.IsFeatureDisabledWithLoginType(ctx.Doer, setting.UserFeatureManageSSHKeys) { - ctx.NotFound(fmt.Errorf("ssh keys setting is not allowed to be visited")) + ctx.NotFound(errors.New("ssh keys setting is not allowed to be visited")) return } diff --git a/routers/web/web.go b/routers/web/web.go index 1658ba15f4..fcddcad1b1 100644 --- a/routers/web/web.go +++ b/routers/web/web.go @@ -178,7 +178,7 @@ func verifyAuthWithOptions(options *common.VerifyOptions) func(ctx *context.Cont return } - if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == "POST" { + if !options.SignOutRequired && !options.DisableCSRF && ctx.Req.Method == http.MethodPost { ctx.Csrf.Validate(ctx) if ctx.Written() { return @@ -283,23 +283,23 @@ func Routes() *web.Router { mid = append(mid, goGet) mid = append(mid, common.PageTmplFunctions) - others := web.NewRouter() - others.Use(mid...) - registerRoutes(others) - routes.Mount("", others) + webRoutes := web.NewRouter() + webRoutes.Use(mid...) + webRoutes.Group("", func() { registerWebRoutes(webRoutes) }, common.BlockExpensive()) + routes.Mount("", webRoutes) return routes } var optSignInIgnoreCsrf = verifyAuthWithOptions(&common.VerifyOptions{DisableCSRF: true}) -// registerRoutes register routes -func registerRoutes(m *web.Router) { +// registerWebRoutes register routes +func registerWebRoutes(m *web.Router) { // required to be signed in or signed out reqSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: true}) reqSignOut := verifyAuthWithOptions(&common.VerifyOptions{SignOutRequired: true}) // optional sign in (if signed in, use the user as doer, if not, no doer) - optSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView}) - optExploreSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInView || setting.Service.Explore.RequireSigninView}) + optSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInViewStrict}) + optExploreSignIn := verifyAuthWithOptions(&common.VerifyOptions{SignInRequired: setting.Service.RequireSignInViewStrict || setting.Service.Explore.RequireSigninView}) validation.AddBindingRules() @@ -1211,7 +1211,7 @@ func registerRoutes(m *web.Router) { m.Get("/comments/{id}/attachments", repo.GetCommentAttachments) m.Get("/labels", repo.RetrieveLabelsForList, repo.Labels) m.Get("/milestones", repo.Milestones) - m.Get("/milestone/{id}", context.RepoRef(), repo.MilestoneIssuesAndPulls) + m.Get("/milestone/{id}", repo.MilestoneIssuesAndPulls) m.Get("/issues/suggestions", repo.IssueSuggestions) }, optSignIn, context.RepoAssignment, reqRepoIssuesOrPullsReader) // issue/pull attachments, labels, milestones // end "/{username}/{reponame}": view milestone, label, issue, pull, etc @@ -1225,9 +1225,9 @@ func registerRoutes(m *web.Router) { m.Group("/{username}/{reponame}", func() { // edit issues, pulls, labels, milestones, etc m.Group("/issues", func() { m.Group("/new", func() { - m.Combo("").Get(context.RepoRef(), repo.NewIssue). + m.Combo("").Get(repo.NewIssue). Post(web.Bind(forms.CreateIssueForm{}), repo.NewIssuePost) - m.Get("/choose", context.RepoRef(), repo.NewIssueChooseTemplate) + m.Get("/choose", repo.NewIssueChooseTemplate) }) m.Get("/search", repo.SearchRepoIssuesJSON) }, reqUnitIssuesReader) @@ -1290,7 +1290,7 @@ func registerRoutes(m *web.Router) { m.Post("/edit", web.Bind(forms.CreateLabelForm{}), repo.UpdateLabel) m.Post("/delete", repo.DeleteLabel) m.Post("/initialize", web.Bind(forms.InitializeLabelsForm{}), repo.InitializeLabels) - }, reqRepoIssuesOrPullsWriter, context.RepoRef()) + }, reqRepoIssuesOrPullsWriter) m.Group("/milestones", func() { m.Combo("/new").Get(repo.NewMilestone). @@ -1299,7 +1299,7 @@ func registerRoutes(m *web.Router) { m.Post("/{id}/edit", web.Bind(forms.CreateMilestoneForm{}), repo.EditMilestonePost) m.Post("/{id}/{action}", repo.ChangeMilestoneStatus) m.Post("/delete", repo.DeleteMilestone) - }, reqRepoIssuesOrPullsWriter, context.RepoRef()) + }, reqRepoIssuesOrPullsWriter) // FIXME: many "pulls" requests are sent to "issues" endpoints incorrectly, need to move these routes to the proper place m.Group("/issues", func() { @@ -1377,7 +1377,7 @@ func registerRoutes(m *web.Router) { m.Post("/delete", repo.DeleteRelease) m.Post("/attachments", repo.UploadReleaseAttachment) m.Post("/attachments/remove", repo.DeleteAttachment) - }, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter, context.RepoRef()) + }, reqSignIn, context.RepoMustNotBeArchived(), reqRepoReleaseWriter) m.Group("/releases", func() { m.Get("/edit/*", repo.EditRelease) m.Post("/edit/*", web.Bind(forms.EditReleaseForm{}), repo.EditReleasePost) @@ -1506,19 +1506,19 @@ func registerRoutes(m *web.Router) { m.Get(".diff", repo.DownloadPullDiff) m.Get(".patch", repo.DownloadPullPatch) m.Group("/commits", func() { - m.Get("", context.RepoRef(), repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits) - m.Get("/list", context.RepoRef(), repo.GetPullCommits) - m.Get("/{sha:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit) + m.Get("", repo.SetWhitespaceBehavior, repo.GetPullDiffStats, repo.ViewPullCommits) + m.Get("/list", repo.GetPullCommits) + m.Get("/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForSingleCommit) }) m.Post("/merge", context.RepoMustNotBeArchived(), web.Bind(forms.MergePullRequestForm{}), repo.MergePullRequest) m.Post("/cancel_auto_merge", context.RepoMustNotBeArchived(), repo.CancelAutoMergePullRequest) m.Post("/update", repo.UpdatePullRequest) m.Post("/set_allow_maintainer_edit", web.Bind(forms.UpdateAllowEditsForm{}), repo.SetAllowEdits) - m.Post("/cleanup", context.RepoMustNotBeArchived(), context.RepoRef(), repo.CleanUpPullRequest) + m.Post("/cleanup", context.RepoMustNotBeArchived(), repo.CleanUpPullRequest) m.Group("/files", func() { - m.Get("", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForAllCommitsOfPr) - m.Get("/{sha:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit) - m.Get("/{shaFrom:[a-f0-9]{7,40}}..{shaTo:[a-f0-9]{7,40}}", context.RepoRef(), repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange) + m.Get("", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForAllCommitsOfPr) + m.Get("/{sha:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesStartingFromCommit) + m.Get("/{shaFrom:[a-f0-9]{7,40}}..{shaTo:[a-f0-9]{7,40}}", repo.SetEditorconfigIfExists, repo.SetDiffViewStyle, repo.SetWhitespaceBehavior, repo.SetShowOutdatedComments, repo.ViewPullFilesForRange) m.Group("/reviews", func() { m.Get("/new_comment", repo.RenderNewCodeCommentForm) m.Post("/comments", web.Bind(forms.CodeCommentForm{}), repo.SetShowOutdatedComments, repo.CreateCodeComment) @@ -1605,7 +1605,7 @@ func registerRoutes(m *web.Router) { m.Get("/tree/*", repo.RedirectRepoTreeToSrc) // redirect "/owner/repo/tree/*" requests to "/owner/repo/src/*" m.Get("/blob/*", repo.RedirectRepoBlobToCommit) // redirect "/owner/repo/blob/*" requests to "/owner/repo/src/commit/*" - m.Get("/forks", context.RepoRef(), repo.Forks) + m.Get("/forks", repo.Forks) m.Get("/commit/{sha:([a-f0-9]{7,64})}.{ext:patch|diff}", repo.MustBeNotEmpty, repo.RawDiff) m.Post("/lastcommit/*", context.RepoRefByType(git.RefTypeCommit), repo.LastCommit) }, optSignIn, context.RepoAssignment, reqUnitCodeReader) diff --git a/routers/web/webfinger.go b/routers/web/webfinger.go index afcfdc8252..a4c9bf902b 100644 --- a/routers/web/webfinger.go +++ b/routers/web/webfinger.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" user_model "code.gitea.io/gitea/models/user" @@ -85,10 +86,10 @@ func WebfingerQuery(ctx *context.Context) { aliases := []string{ u.HTMLURL(), - appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(u.ID), + appURL.String() + "api/v1/activitypub/user-id/" + strconv.FormatInt(u.ID, 10), } if !u.KeepEmailPrivate { - aliases = append(aliases, fmt.Sprintf("mailto:%s", u.Email)) + aliases = append(aliases, "mailto:"+u.Email) } links := []*webfingerLink{ @@ -104,7 +105,7 @@ func WebfingerQuery(ctx *context.Context) { { Rel: "self", Type: "application/activity+json", - Href: appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(u.ID), + Href: appURL.String() + "api/v1/activitypub/user-id/" + strconv.FormatInt(u.ID, 10), }, { Rel: "http://openid.net/specs/connect/1.0/issuer", diff --git a/services/actions/auth.go b/services/actions/auth.go index 1ef21f6e0e..12a8fba53f 100644 --- a/services/actions/auth.go +++ b/services/actions/auth.go @@ -4,6 +4,7 @@ package actions import ( + "errors" "fmt" "net/http" "strings" @@ -80,7 +81,7 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) { parts := strings.SplitN(h, " ", 2) if len(parts) != 2 { log.Error("split token failed: %s", h) - return 0, fmt.Errorf("split token failed") + return 0, errors.New("split token failed") } return TokenToTaskID(parts[1]) @@ -100,7 +101,7 @@ func TokenToTaskID(token string) (int64, error) { c, ok := parsedToken.Claims.(*actionsClaims) if !parsedToken.Valid || !ok { - return 0, fmt.Errorf("invalid token claim") + return 0, errors.New("invalid token claim") } return c.TaskID, nil diff --git a/services/actions/auth_test.go b/services/actions/auth_test.go index 85e7409105..38d0ba7f82 100644 --- a/services/actions/auth_test.go +++ b/services/actions/auth_test.go @@ -18,7 +18,7 @@ func TestCreateAuthorizationToken(t *testing.T) { var taskID int64 = 23 token, err := CreateAuthorizationToken(taskID, 1, 2) assert.NoError(t, err) - assert.NotEqual(t, "", token) + assert.NotEmpty(t, token) claims := jwt.MapClaims{} _, err = jwt.ParseWithClaims(token, claims, func(t *jwt.Token) (any, error) { return setting.GetGeneralTokenSigningSecret(), nil @@ -44,7 +44,7 @@ func TestParseAuthorizationToken(t *testing.T) { var taskID int64 = 23 token, err := CreateAuthorizationToken(taskID, 1, 2) assert.NoError(t, err) - assert.NotEqual(t, "", token) + assert.NotEmpty(t, token) headers := http.Header{} headers.Set("Authorization", "Bearer "+token) rTaskID, err := ParseAuthorizationToken(&http.Request{ diff --git a/services/actions/commit_status.go b/services/actions/commit_status.go index 94ab89a3b7..eb15d16061 100644 --- a/services/actions/commit_status.go +++ b/services/actions/commit_status.go @@ -5,6 +5,7 @@ package actions import ( "context" + "errors" "fmt" "path" @@ -51,7 +52,7 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er return fmt.Errorf("GetPushEventPayload: %w", err) } if payload.HeadCommit == nil { - return fmt.Errorf("head commit is missing in event payload") + return errors.New("head commit is missing in event payload") } sha = payload.HeadCommit.ID case // pull_request @@ -71,9 +72,9 @@ func createCommitStatus(ctx context.Context, job *actions_model.ActionRunJob) er return fmt.Errorf("GetPullRequestEventPayload: %w", err) } if payload.PullRequest == nil { - return fmt.Errorf("pull request is missing in event payload") + return errors.New("pull request is missing in event payload") } else if payload.PullRequest.Head == nil { - return fmt.Errorf("head of pull request is missing in event payload") + return errors.New("head of pull request is missing in event payload") } sha = payload.PullRequest.Head.Sha case webhook_module.HookEventRelease: diff --git a/services/actions/context.go b/services/actions/context.go index d14728fae4..2667e18337 100644 --- a/services/actions/context.go +++ b/services/actions/context.go @@ -6,6 +6,7 @@ package actions import ( "context" "fmt" + "strconv" actions_model "code.gitea.io/gitea/models/actions" "code.gitea.io/gitea/models/db" @@ -68,7 +69,7 @@ func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.Actio "repositoryUrl": run.Repo.HTMLURL(), // string, The Git URL to the repository. For example, git://github.com/codertocat/hello-world.git. "retention_days": "", // string, The number of days that workflow run logs and artifacts are kept. "run_id": "", // string, A unique number for each workflow run within a repository. This number does not change if you re-run the workflow run. - "run_number": fmt.Sprint(run.Index), // string, A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run. + "run_number": strconv.FormatInt(run.Index, 10), // string, A unique number for each run of a particular workflow in a repository. This number begins at 1 for the workflow's first run, and increments with each new run. This number does not change if you re-run the workflow run. "run_attempt": "", // string, A unique number for each attempt of a particular workflow run in a repository. This number begins at 1 for the workflow run's first attempt, and increments with each re-run. "secret_source": "Actions", // string, The source of a secret used in a workflow. Possible values are None, Actions, Dependabot, or Codespaces. "server_url": setting.AppURL, // string, The URL of the GitHub server. For example: https://github.com. @@ -83,8 +84,8 @@ func GenerateGiteaContext(run *actions_model.ActionRun, job *actions_model.Actio if job != nil { gitContext["job"] = job.JobID - gitContext["run_id"] = fmt.Sprint(job.RunID) - gitContext["run_attempt"] = fmt.Sprint(job.Attempt) + gitContext["run_id"] = strconv.FormatInt(job.RunID, 10) + gitContext["run_attempt"] = strconv.FormatInt(job.Attempt, 10) } return gitContext diff --git a/services/actions/task.go b/services/actions/task.go index 9c8198206a..6a547c1c12 100644 --- a/services/actions/task.go +++ b/services/actions/task.go @@ -5,6 +5,7 @@ package actions import ( "context" + "errors" "fmt" actions_model "code.gitea.io/gitea/models/actions" @@ -39,7 +40,7 @@ func PickTask(ctx context.Context, runner *actions_model.ActionRunner) (*runnerv if err != nil { return nil, false, err } - return nil, false, fmt.Errorf("runner has been removed") + return nil, false, errors.New("runner has been removed") } } diff --git a/services/asymkey/commit.go b/services/asymkey/commit.go index df29133972..5d85be56f1 100644 --- a/services/asymkey/commit.go +++ b/services/asymkey/commit.go @@ -5,6 +5,7 @@ package asymkey import ( "context" + "fmt" "strings" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -14,6 +15,7 @@ import ( "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" + "github.com/42wim/sshsig" "github.com/ProtonMail/go-crypto/openpgp/packet" ) @@ -57,7 +59,7 @@ func ParseCommitWithSignatureCommitter(ctx context.Context, c *git.Commit, commi // If this a SSH signature handle it differently if strings.HasPrefix(c.Signature.Signature, "-----BEGIN SSH SIGNATURE-----") { - return asymkey_model.ParseCommitWithSSHSignature(ctx, c, committer) + return ParseCommitWithSSHSignature(ctx, c, committer) } // Parsing signature @@ -361,3 +363,65 @@ func VerifyWithGPGSettings(ctx context.Context, gpgSettings *git.GPGSettings, si } return nil } + +// ParseCommitWithSSHSignature check if signature is good against keystore. +func ParseCommitWithSSHSignature(ctx context.Context, c *git.Commit, committer *user_model.User) *asymkey_model.CommitVerification { + // Now try to associate the signature with the committer, if present + if committer.ID != 0 { + keys, err := db.Find[asymkey_model.PublicKey](ctx, asymkey_model.FindPublicKeyOptions{ + OwnerID: committer.ID, + NotKeytype: asymkey_model.KeyTypePrincipal, + }) + if err != nil { // Skipping failed to get ssh keys of user + log.Error("ListPublicKeys: %v", err) + return &asymkey_model.CommitVerification{ + CommittingUser: committer, + Verified: false, + Reason: "gpg.error.failed_retrieval_gpg_keys", + } + } + + committerEmailAddresses, err := user_model.GetEmailAddresses(ctx, committer.ID) + if err != nil { + log.Error("GetEmailAddresses: %v", err) + } + + activated := false + for _, e := range committerEmailAddresses { + if e.IsActivated && strings.EqualFold(e.Email, c.Committer.Email) { + activated = true + break + } + } + + for _, k := range keys { + if k.Verified && activated { + commitVerification := verifySSHCommitVerification(c.Signature.Signature, c.Signature.Payload, k, committer, committer, c.Committer.Email) + if commitVerification != nil { + return commitVerification + } + } + } + } + + return &asymkey_model.CommitVerification{ + CommittingUser: committer, + Verified: false, + Reason: asymkey_model.NoKeyFound, + } +} + +func verifySSHCommitVerification(sig, payload string, k *asymkey_model.PublicKey, committer, signer *user_model.User, email string) *asymkey_model.CommitVerification { + if err := sshsig.Verify(strings.NewReader(payload), []byte(sig), []byte(k.Content), "git"); err != nil { + return nil + } + + return &asymkey_model.CommitVerification{ // Everything is ok + CommittingUser: committer, + Verified: true, + Reason: fmt.Sprintf("%s / %s", signer.Name, k.Fingerprint), + SigningUser: signer, + SigningSSHKey: k, + SigningEmail: email, + } +} diff --git a/services/attachment/attachment_test.go b/services/attachment/attachment_test.go index 142bcfe629..65475836be 100644 --- a/services/attachment/attachment_test.go +++ b/services/attachment/attachment_test.go @@ -41,6 +41,6 @@ func TestUploadAttachment(t *testing.T) { attachment, err := repo_model.GetAttachmentByUUID(db.DefaultContext, attach.UUID) assert.NoError(t, err) - assert.EqualValues(t, user.ID, attachment.UploaderID) + assert.Equal(t, user.ID, attachment.UploaderID) assert.Equal(t, int64(0), attachment.DownloadCount) } diff --git a/services/auth/auth.go b/services/auth/auth.go index f7deeb4c50..fb6612290b 100644 --- a/services/auth/auth.go +++ b/services/auth/auth.go @@ -62,14 +62,14 @@ func (a *authPathDetector) isAPIPath() bool { // isAttachmentDownload check if request is a file download (GET) with URL to an attachment func (a *authPathDetector) isAttachmentDownload() bool { - return strings.HasPrefix(a.req.URL.Path, "/attachments/") && a.req.Method == "GET" + return strings.HasPrefix(a.req.URL.Path, "/attachments/") && a.req.Method == http.MethodGet } func (a *authPathDetector) isFeedRequest(req *http.Request) bool { if !setting.Other.EnableFeed { return false } - if req.Method != "GET" { + if req.Method != http.MethodGet { return false } return a.vars.feedPathRe.MatchString(req.URL.Path) || a.vars.feedRefPathRe.MatchString(req.URL.Path) diff --git a/services/auth/auth_test.go b/services/auth/auth_test.go index b8d3396163..c45f312c90 100644 --- a/services/auth/auth_test.go +++ b/services/auth/auth_test.go @@ -97,7 +97,7 @@ func Test_isGitRawOrLFSPath(t *testing.T) { defer test.MockVariableValue(&setting.LFS.StartServer)() for _, tt := range tests { t.Run(tt.path, func(t *testing.T) { - req, _ := http.NewRequest("POST", "http://localhost"+tt.path, nil) + req, _ := http.NewRequest(http.MethodPost, "http://localhost"+tt.path, nil) setting.LFS.StartServer = false assert.Equal(t, tt.want, newAuthPathDetector(req).isGitRawOrAttachOrLFSPath()) @@ -119,7 +119,7 @@ func Test_isGitRawOrLFSPath(t *testing.T) { } for _, tt := range lfsTests { t.Run(tt, func(t *testing.T) { - req, _ := http.NewRequest("POST", tt, nil) + req, _ := http.NewRequest(http.MethodPost, tt, nil) setting.LFS.StartServer = false got := newAuthPathDetector(req).isGitRawOrAttachOrLFSPath() assert.Equalf(t, setting.LFS.StartServer, got, "isGitOrLFSPath(%q) = %v, want %v, %v", tt, got, setting.LFS.StartServer, globalVars().gitRawOrAttachPathRe.MatchString(tt)) @@ -148,7 +148,7 @@ func Test_isFeedRequest(t *testing.T) { } for _, tt := range tests { t.Run(tt.path, func(t *testing.T) { - req, _ := http.NewRequest("GET", "http://localhost"+tt.path, nil) + req, _ := http.NewRequest(http.MethodGet, "http://localhost"+tt.path, nil) assert.Equal(t, tt.want, newAuthPathDetector(req).isFeedRequest(req)) }) } diff --git a/services/auth/httpsign.go b/services/auth/httpsign.go index 83a36bef23..25e96ff32d 100644 --- a/services/auth/httpsign.go +++ b/services/auth/httpsign.go @@ -134,7 +134,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) { // Check if it's really a ssh certificate cert, ok := pk.(*ssh.Certificate) if !ok { - return nil, fmt.Errorf("no certificate found") + return nil, errors.New("no certificate found") } c := &ssh.CertChecker{ @@ -153,7 +153,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) { // check the CA of the cert if !c.IsUserAuthority(cert.SignatureKey) { - return nil, fmt.Errorf("CA check failed") + return nil, errors.New("CA check failed") } // Create a verifier @@ -191,7 +191,7 @@ func VerifyCert(r *http.Request) (*asymkey_model.PublicKey, error) { } // No public key matching a principal in the certificate is registered in gitea - return nil, fmt.Errorf("no valid principal found") + return nil, errors.New("no valid principal found") } // doVerify iterates across the provided public keys attempting the verify the current request against each key in turn diff --git a/services/auth/source/ldap/source_authenticate.go b/services/auth/source/ldap/source_authenticate.go index 6a6c60cd40..7aee761d0d 100644 --- a/services/auth/source/ldap/source_authenticate.go +++ b/services/auth/source/ldap/source_authenticate.go @@ -5,7 +5,6 @@ package ldap import ( "context" - "fmt" "strings" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -41,7 +40,7 @@ func (source *Source) Authenticate(ctx context.Context, user *user_model.User, u sr.Username = userName } if sr.Mail == "" { - sr.Mail = fmt.Sprintf("%s@localhost.local", sr.Username) + sr.Mail = sr.Username + "@localhost.local" } isAttributeSSHPublicKeySet := strings.TrimSpace(source.AttributeSSHPublicKey) != "" diff --git a/services/auth/source/ldap/source_sync.go b/services/auth/source/ldap/source_sync.go index e817bf1fa9..ff36db2955 100644 --- a/services/auth/source/ldap/source_sync.go +++ b/services/auth/source/ldap/source_sync.go @@ -5,7 +5,6 @@ package ldap import ( "context" - "fmt" "strings" asymkey_model "code.gitea.io/gitea/models/asymkey" @@ -106,7 +105,7 @@ func (source *Source) Sync(ctx context.Context, updateExisting bool) error { } if su.Mail == "" { - su.Mail = fmt.Sprintf("%s@localhost.local", su.Username) + su.Mail = su.Username + "@localhost.local" } fullName := composeFullName(su.Name, su.Surname, su.Username) diff --git a/services/auth/source/oauth2/source_sync_test.go b/services/auth/source/oauth2/source_sync_test.go index aacb4286a1..08d841cc90 100644 --- a/services/auth/source/oauth2/source_sync_test.go +++ b/services/auth/source/oauth2/source_sync_test.go @@ -88,8 +88,8 @@ func TestSource(t *testing.T) { ok, err := user_model.GetExternalLogin(t.Context(), e) assert.NoError(t, err) assert.True(t, ok) - assert.Equal(t, "", e.RefreshToken) - assert.Equal(t, "", e.AccessToken) + assert.Empty(t, e.RefreshToken) + assert.Empty(t, e.AccessToken) u, err := user_model.GetUserByID(t.Context(), user.ID) assert.NoError(t, err) diff --git a/services/automerge/automerge.go b/services/automerge/automerge.go index 62d560ff94..9d2f7f4857 100644 --- a/services/automerge/automerge.go +++ b/services/automerge/automerge.go @@ -36,7 +36,7 @@ func Init() error { prAutoMergeQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_auto_merge", handler) if prAutoMergeQueue == nil { - return fmt.Errorf("unable to create pr_auto_merge queue") + return errors.New("unable to create pr_auto_merge queue") } go graceful.GetManager().RunWithCancel(prAutoMergeQueue) return nil diff --git a/services/context/access_log.go b/services/context/access_log.go index 925e4a3056..caade113a7 100644 --- a/services/context/access_log.go +++ b/services/context/access_log.go @@ -5,7 +5,6 @@ package context import ( "bytes" - "fmt" "net" "net/http" "strings" @@ -47,7 +46,7 @@ func parseRequestIDFromRequestHeader(req *http.Request) string { } } if len(requestID) > maxRequestIDByteLength { - requestID = fmt.Sprintf("%s...", requestID[:maxRequestIDByteLength]) + requestID = requestID[:maxRequestIDByteLength] + "..." } return requestID } diff --git a/services/context/access_log_test.go b/services/context/access_log_test.go index c40ef9acd1..139a6eb217 100644 --- a/services/context/access_log_test.go +++ b/services/context/access_log_test.go @@ -59,7 +59,7 @@ func TestAccessLogger(t *testing.T) { recorder.logger = mockLogger req := &http.Request{ RemoteAddr: "remote-addr", - Method: "GET", + Method: http.MethodGet, Proto: "https", URL: &url.URL{Path: "/path"}, } diff --git a/services/context/api.go b/services/context/api.go index 10fad419ba..6e3b635ce3 100644 --- a/services/context/api.go +++ b/services/context/api.go @@ -9,6 +9,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" "code.gitea.io/gitea/models/unit" @@ -168,7 +169,7 @@ func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string { if paginater.HasNext() { u := *curURL queries := u.Query() - queries.Set("page", fmt.Sprintf("%d", paginater.Next())) + queries.Set("page", strconv.Itoa(paginater.Next())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"next\"", setting.AppURL, u.RequestURI()[1:])) @@ -176,7 +177,7 @@ func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string { if !paginater.IsLast() { u := *curURL queries := u.Query() - queries.Set("page", fmt.Sprintf("%d", paginater.TotalPages())) + queries.Set("page", strconv.Itoa(paginater.TotalPages())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"last\"", setting.AppURL, u.RequestURI()[1:])) @@ -192,7 +193,7 @@ func genAPILinks(curURL *url.URL, total, pageSize, curPage int) []string { if paginater.HasPrevious() { u := *curURL queries := u.Query() - queries.Set("page", fmt.Sprintf("%d", paginater.Previous())) + queries.Set("page", strconv.Itoa(paginater.Previous())) u.RawQuery = queries.Encode() links = append(links, fmt.Sprintf("<%s%s>; rel=\"prev\"", setting.AppURL, u.RequestURI()[1:])) @@ -225,7 +226,7 @@ func APIContexter() func(http.Handler) http.Handler { ctx.SetContextValue(apiContextKey, ctx) // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. - if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { + if ctx.Req.Method == http.MethodPost && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size ctx.APIErrorInternal(err) return @@ -297,7 +298,7 @@ func RepoRefForAPI(next http.Handler) http.Handler { } if ctx.Repo.GitRepo == nil { - ctx.APIErrorInternal(fmt.Errorf("no open git repo")) + ctx.APIErrorInternal(errors.New("no open git repo")) return } diff --git a/services/context/api_test.go b/services/context/api_test.go index 911a49949e..87d74004db 100644 --- a/services/context/api_test.go +++ b/services/context/api_test.go @@ -45,6 +45,6 @@ func TestGenAPILinks(t *testing.T) { links := genAPILinks(u, 100, 20, curPage) - assert.EqualValues(t, links, response) + assert.Equal(t, links, response) } } diff --git a/services/context/base.go b/services/context/base.go index 3701668bf6..f3f92b7eeb 100644 --- a/services/context/base.go +++ b/services/context/base.go @@ -8,6 +8,7 @@ import ( "html/template" "io" "net/http" + "strconv" "strings" "code.gitea.io/gitea/modules/httplib" @@ -53,7 +54,7 @@ func (b *Base) AppendAccessControlExposeHeaders(names ...string) { // SetTotalCountHeader set "X-Total-Count" header func (b *Base) SetTotalCountHeader(total int64) { - b.RespHeader().Set("X-Total-Count", fmt.Sprint(total)) + b.RespHeader().Set("X-Total-Count", strconv.FormatInt(total, 10)) b.AppendAccessControlExposeHeaders("X-Total-Count") } diff --git a/services/context/base_test.go b/services/context/base_test.go index b936b76f58..2a4f86dddf 100644 --- a/services/context/base_test.go +++ b/services/context/base_test.go @@ -15,7 +15,7 @@ import ( func TestRedirect(t *testing.T) { setting.IsInTesting = true - req, _ := http.NewRequest("GET", "/", nil) + req, _ := http.NewRequest(http.MethodGet, "/", nil) cases := []struct { url string @@ -36,7 +36,7 @@ func TestRedirect(t *testing.T) { assert.Equal(t, c.keep, has, "url = %q", c.url) } - req, _ = http.NewRequest("GET", "/", nil) + req, _ = http.NewRequest(http.MethodGet, "/", nil) resp := httptest.NewRecorder() req.Header.Add("HX-Request", "true") b := NewBaseContextForTest(resp, req) diff --git a/services/context/context.go b/services/context/context.go index 79bc5da920..3c0ac54fc1 100644 --- a/services/context/context.go +++ b/services/context/context.go @@ -184,7 +184,7 @@ func Contexter() func(next http.Handler) http.Handler { }) // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid. - if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { + if ctx.Req.Method == http.MethodPost && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") { if err := ctx.Req.ParseMultipartForm(setting.Attachment.MaxSize << 20); err != nil && !strings.Contains(err.Error(), "EOF") { // 32MB max size ctx.ServerError("ParseMultipartForm", err) return diff --git a/services/context/context_response.go b/services/context/context_response.go index 61b432395a..4e11e29b69 100644 --- a/services/context/context_response.go +++ b/services/context/context_response.go @@ -150,7 +150,7 @@ func (ctx *Context) notFoundInternal(logMsg string, logErr error) { ctx.Data["IsRepo"] = ctx.Repo.Repository != nil ctx.Data["Title"] = "Page Not Found" - ctx.HTML(http.StatusNotFound, templates.TplName("status/404")) + ctx.HTML(http.StatusNotFound, "status/404") } // ServerError displays a 500 (Internal Server Error) page and prints the given error, if any. diff --git a/services/context/package.go b/services/context/package.go index 64bb4f3ecd..8b722932b1 100644 --- a/services/context/package.go +++ b/services/context/package.go @@ -93,7 +93,7 @@ func packageAssignment(ctx *packageAssignmentCtx, errCb func(int, any)) *Package } func determineAccessMode(ctx *Base, pkg *Package, doer *user_model.User) (perm.AccessMode, error) { - if setting.Service.RequireSignInView && (doer == nil || doer.IsGhost()) { + if setting.Service.RequireSignInViewStrict && (doer == nil || doer.IsGhost()) { return perm.AccessModeNone, nil } diff --git a/services/context/private.go b/services/context/private.go index 51857da8fe..3f7637518b 100644 --- a/services/context/private.go +++ b/services/context/private.go @@ -5,7 +5,6 @@ package context import ( "context" - "fmt" "net/http" "time" @@ -82,7 +81,7 @@ func OverrideContext() func(http.Handler) http.Handler { // We now need to override the request context as the base for our work because even if the request is cancelled we have to continue this work ctx := GetPrivateContext(req) var finished func() - ctx.Override, _, finished = process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), fmt.Sprintf("PrivateContext: %s", ctx.Req.RequestURI), process.RequestProcessType, true) + ctx.Override, _, finished = process.GetManager().AddTypedContext(graceful.GetManager().HammerContext(), "PrivateContext: "+ctx.Req.RequestURI, process.RequestProcessType, true) defer finished() next.ServeHTTP(ctx.Resp, ctx.Req) }) diff --git a/services/context/repo.go b/services/context/repo.go index 7d0b44c42f..6f5c772f5e 100644 --- a/services/context/repo.go +++ b/services/context/repo.go @@ -669,12 +669,6 @@ func RepoAssignment(ctx *Context) { const headRefName = "HEAD" -func RepoRef() func(*Context) { - // old code does: return RepoRefByType(git.RefTypeBranch) - // in most cases, it is an abuse, so we just disable it completely and fix the abuses one by one (if there is anything wrong) - return nil -} - func getRefNameFromPath(repo *Repository, path string, isExist func(string) bool) string { refName := "" parts := strings.Split(path, "/") @@ -817,9 +811,9 @@ func RepoRefByType(detectRefType git.RefType) func(*Context) { if reqPath == "" { refShortName = ctx.Repo.Repository.DefaultBranch if !gitrepo.IsBranchExist(ctx, ctx.Repo.Repository, refShortName) { - brs, _, err := ctx.Repo.GitRepo.GetBranches(0, 1) + brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 1) if err == nil && len(brs) != 0 { - refShortName = brs[0].Name + refShortName = brs[0] } else if len(brs) == 0 { log.Error("No branches in non-empty repository %s", ctx.Repo.GitRepo.Path) } else { diff --git a/services/convert/git_commit_test.go b/services/convert/git_commit_test.go index 73cb5e8c71..ad1cc0eca3 100644 --- a/services/convert/git_commit_test.go +++ b/services/convert/git_commit_test.go @@ -33,7 +33,7 @@ func TestToCommitMeta(t *testing.T) { commitMeta := ToCommitMeta(headRepo, tag) assert.NotNil(t, commitMeta) - assert.EqualValues(t, &api.CommitMeta{ + assert.Equal(t, &api.CommitMeta{ SHA: sha1.EmptyObjectID().String(), URL: util.URLJoin(headRepo.APIURL(), "git/commits", sha1.EmptyObjectID().String()), Created: time.Unix(0, 0), diff --git a/services/convert/pull.go b/services/convert/pull.go index 928534ce5e..34c3b1bf9a 100644 --- a/services/convert/pull.go +++ b/services/convert/pull.go @@ -28,8 +28,8 @@ import ( // Optional - Merger func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User) *api.PullRequest { var ( - baseBranch *git.Branch - headBranch *git.Branch + baseBranch string + headBranch string baseCommit *git.Commit err error ) @@ -150,16 +150,16 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u } defer gitRepo.Close() - baseBranch, err = gitRepo.GetBranch(pr.BaseBranch) - if err != nil && !git.IsErrBranchNotExist(err) { + exist, err := git_model.IsBranchExist(ctx, pr.BaseRepoID, pr.BaseBranch) + if err != nil { log.Error("GetBranch[%s]: %v", pr.BaseBranch, err) return nil } - if err == nil { - baseCommit, err = baseBranch.GetCommit() + if exist { + baseCommit, err = gitRepo.GetBranchCommit(pr.BaseBranch) if err != nil && !git.IsErrNotExist(err) { - log.Error("GetCommit[%s]: %v", baseBranch.Name, err) + log.Error("GetCommit[%s]: %v", baseBranch, err) return nil } @@ -169,13 +169,6 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u } if pr.Flow == issues_model.PullRequestFlowAGit { - gitRepo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo) - if err != nil { - log.Error("OpenRepository[%s]: %v", pr.GetGitRefName(), err) - return nil - } - defer gitRepo.Close() - apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) if err != nil { log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) @@ -203,8 +196,8 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u } defer headGitRepo.Close() - headBranch, err = headGitRepo.GetBranch(pr.HeadBranch) - if err != nil && !git.IsErrBranchNotExist(err) { + exist, err = git_model.IsBranchExist(ctx, pr.HeadRepoID, pr.HeadBranch) + if err != nil { log.Error("GetBranch[%s]: %v", pr.HeadBranch, err) return nil } @@ -215,7 +208,7 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u endCommitID string ) - if git.IsErrBranchNotExist(err) { + if !exist { headCommitID, err := headGitRepo.GetRefCommitID(apiPullRequest.Head.Ref) if err != nil && !git.IsErrNotExist(err) { log.Error("GetCommit[%s]: %v", pr.HeadBranch, err) @@ -226,9 +219,9 @@ func ToAPIPullRequest(ctx context.Context, pr *issues_model.PullRequest, doer *u endCommitID = headCommitID } } else { - commit, err := headBranch.GetCommit() + commit, err := headGitRepo.GetBranchCommit(pr.HeadBranch) if err != nil && !git.IsErrNotExist(err) { - log.Error("GetCommit[%s]: %v", headBranch.Name, err) + log.Error("GetCommit[%s]: %v", headBranch, err) return nil } if err == nil { @@ -389,7 +382,7 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs }, Head: &api.PRBranchInfo{ Name: pr.HeadBranch, - Ref: fmt.Sprintf("%s%d/head", git.PullPrefix, pr.Index), + Ref: pr.GetGitRefName(), RepoID: -1, }, } @@ -422,72 +415,43 @@ func ToAPIPullRequests(ctx context.Context, baseRepo *repo_model.Repository, prs return nil, err } } - if baseBranch != nil { apiPullRequest.Base.Sha = baseBranch.CommitID } - if pr.Flow == issues_model.PullRequestFlowAGit { - apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) + // pull request head branch, both repository and branch could not exist + if pr.HeadRepo != nil { + apiPullRequest.Head.RepoID = pr.HeadRepo.ID + exist, err := git_model.IsBranchExist(ctx, pr.HeadRepo.ID, pr.HeadBranch) if err != nil { - log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) + log.Error("IsBranchExist[%d]: %v", pr.HeadRepo.ID, err) return nil, err } - apiPullRequest.Head.RepoID = pr.BaseRepoID - apiPullRequest.Head.Repository = apiPullRequest.Base.Repository - apiPullRequest.Head.Name = "" + if exist { + apiPullRequest.Head.Ref = pr.HeadBranch + } + } + if apiPullRequest.Head.Ref == "" { + apiPullRequest.Head.Ref = pr.GetGitRefName() } - var headGitRepo *git.Repository - if pr.HeadRepo != nil && pr.Flow == issues_model.PullRequestFlowGithub { - if pr.HeadRepoID == pr.BaseRepoID { - apiPullRequest.Head.RepoID = pr.HeadRepo.ID - apiPullRequest.Head.Repository = apiRepo - headGitRepo = gitRepo - } else { - p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) - if err != nil { - log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) - p.AccessMode = perm.AccessModeNone - } - - apiPullRequest.Head.RepoID = pr.HeadRepo.ID - apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p) - - headGitRepo, err = gitrepo.OpenRepository(ctx, pr.HeadRepo) - if err != nil { - log.Error("OpenRepository[%s]: %v", pr.HeadRepo.RepoPath(), err) - return nil, err - } - defer headGitRepo.Close() + if pr.HeadRepoID == pr.BaseRepoID { + apiPullRequest.Head.Repository = apiPullRequest.Base.Repository + } else { + p, err := access_model.GetUserRepoPermission(ctx, pr.HeadRepo, doer) + if err != nil { + log.Error("GetUserRepoPermission[%d]: %v", pr.HeadRepoID, err) + p.AccessMode = perm.AccessModeNone } + apiPullRequest.Head.Repository = ToRepo(ctx, pr.HeadRepo, p) + } - headBranch, err := headGitRepo.GetBranch(pr.HeadBranch) - if err != nil && !git.IsErrBranchNotExist(err) { - log.Error("GetBranch[%s]: %v", pr.HeadBranch, err) - return nil, err - } - - if git.IsErrBranchNotExist(err) { - headCommitID, err := headGitRepo.GetRefCommitID(apiPullRequest.Head.Ref) - if err != nil && !git.IsErrNotExist(err) { - log.Error("GetCommit[%s]: %v", pr.HeadBranch, err) - return nil, err - } - if err == nil { - apiPullRequest.Head.Sha = headCommitID - } - } else { - commit, err := headBranch.GetCommit() - if err != nil && !git.IsErrNotExist(err) { - log.Error("GetCommit[%s]: %v", headBranch.Name, err) - return nil, err - } - if err == nil { - apiPullRequest.Head.Ref = pr.HeadBranch - apiPullRequest.Head.Sha = commit.ID.String() - } - } + if pr.Flow == issues_model.PullRequestFlowAGit { + apiPullRequest.Head.Name = "" + } + apiPullRequest.Head.Sha, err = gitRepo.GetRefCommitID(pr.GetGitRefName()) + if err != nil { + log.Error("GetRefCommitID[%s]: %v", pr.GetGitRefName(), err) } if len(apiPullRequest.Head.Sha) == 0 && len(apiPullRequest.Head.Ref) != 0 { diff --git a/services/convert/pull_review_test.go b/services/convert/pull_review_test.go index a1296fafd4..d0a077ab24 100644 --- a/services/convert/pull_review_test.go +++ b/services/convert/pull_review_test.go @@ -19,8 +19,8 @@ func Test_ToPullReview(t *testing.T) { reviewer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) review := unittest.AssertExistsAndLoadBean(t, &issues_model.Review{ID: 6}) - assert.EqualValues(t, reviewer.ID, review.ReviewerID) - assert.EqualValues(t, issues_model.ReviewTypePending, review.Type) + assert.Equal(t, reviewer.ID, review.ReviewerID) + assert.Equal(t, issues_model.ReviewTypePending, review.Type) reviewList := []*issues_model.Review{review} diff --git a/services/convert/pull_test.go b/services/convert/pull_test.go index e069fa4a68..cd86283c8a 100644 --- a/services/convert/pull_test.go +++ b/services/convert/pull_test.go @@ -27,7 +27,7 @@ func TestPullRequest_APIFormat(t *testing.T) { assert.NoError(t, pr.LoadIssue(db.DefaultContext)) apiPullRequest := ToAPIPullRequest(git.DefaultContext, pr, nil) assert.NotNil(t, apiPullRequest) - assert.EqualValues(t, &structs.PRBranchInfo{ + assert.Equal(t, &structs.PRBranchInfo{ Name: "branch1", Ref: "refs/pull/2/head", Sha: "4a357436d925b5c974181ff12a994538ddc5a269", diff --git a/services/convert/release_test.go b/services/convert/release_test.go index 201b27e16d..bb618c9ca3 100644 --- a/services/convert/release_test.go +++ b/services/convert/release_test.go @@ -23,6 +23,6 @@ func TestRelease_ToRelease(t *testing.T) { apiRelease := ToAPIRelease(db.DefaultContext, repo1, release1) assert.NotNil(t, apiRelease) assert.EqualValues(t, 1, apiRelease.ID) - assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL) - assert.EqualValues(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1/assets", apiRelease.UploadURL) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1", apiRelease.URL) + assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/releases/1/assets", apiRelease.UploadURL) } diff --git a/services/convert/user_test.go b/services/convert/user_test.go index 4b1effc7aa..199d500732 100644 --- a/services/convert/user_test.go +++ b/services/convert/user_test.go @@ -30,11 +30,11 @@ func TestUser_ToUser(t *testing.T) { apiUser = toUser(db.DefaultContext, user1, false, false) assert.False(t, apiUser.IsAdmin) - assert.EqualValues(t, api.VisibleTypePublic.String(), apiUser.Visibility) + assert.Equal(t, api.VisibleTypePublic.String(), apiUser.Visibility) user31 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 31, IsAdmin: false, Visibility: api.VisibleTypePrivate}) apiUser = toUser(db.DefaultContext, user31, true, true) assert.False(t, apiUser.IsAdmin) - assert.EqualValues(t, api.VisibleTypePrivate.String(), apiUser.Visibility) + assert.Equal(t, api.VisibleTypePrivate.String(), apiUser.Visibility) } diff --git a/services/convert/utils_test.go b/services/convert/utils_test.go index a8363ec6bd..7965624e2b 100644 --- a/services/convert/utils_test.go +++ b/services/convert/utils_test.go @@ -10,10 +10,10 @@ import ( ) func TestToCorrectPageSize(t *testing.T) { - assert.EqualValues(t, 30, ToCorrectPageSize(0)) - assert.EqualValues(t, 30, ToCorrectPageSize(-10)) - assert.EqualValues(t, 20, ToCorrectPageSize(20)) - assert.EqualValues(t, 50, ToCorrectPageSize(100)) + assert.Equal(t, 30, ToCorrectPageSize(0)) + assert.Equal(t, 30, ToCorrectPageSize(-10)) + assert.Equal(t, 20, ToCorrectPageSize(20)) + assert.Equal(t, 50, ToCorrectPageSize(100)) } func TestToGitServiceType(t *testing.T) { diff --git a/services/doctor/authorizedkeys.go b/services/doctor/authorizedkeys.go index 8d6fc9cb5e..46e7099dce 100644 --- a/services/doctor/authorizedkeys.go +++ b/services/doctor/authorizedkeys.go @@ -7,6 +7,7 @@ import ( "bufio" "bytes" "context" + "errors" "fmt" "os" "path/filepath" @@ -78,7 +79,7 @@ func checkAuthorizedKeys(ctx context.Context, logger log.Logger, autofix bool) e fPath, "gitea admin regenerate keys", "gitea doctor --run authorized-keys --fix") - return fmt.Errorf(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized-keys --fix"`) + return errors.New(`authorized_keys is out of date and should be regenerated with "gitea admin regenerate keys" or "gitea doctor --run authorized-keys --fix"`) } logger.Warn("authorized_keys is out of date. Attempting rewrite...") err = asymkey_service.RewriteAllPublicKeys(ctx) diff --git a/services/doctor/fix16961_test.go b/services/doctor/fix16961_test.go index d5eded1117..11a128620c 100644 --- a/services/doctor/fix16961_test.go +++ b/services/doctor/fix16961_test.go @@ -215,7 +215,7 @@ func Test_fixPullRequestsConfig_16961(t *testing.T) { if gotFixed != tt.wantFixed { t.Errorf("fixPullRequestsConfig_16961() = %v, want %v", gotFixed, tt.wantFixed) } - assert.EqualValues(t, &tt.expected, cfg) + assert.Equal(t, &tt.expected, cfg) }) } } @@ -259,7 +259,7 @@ func Test_fixIssuesConfig_16961(t *testing.T) { if gotFixed != tt.wantFixed { t.Errorf("fixIssuesConfig_16961() = %v, want %v", gotFixed, tt.wantFixed) } - assert.EqualValues(t, &tt.expected, cfg) + assert.Equal(t, &tt.expected, cfg) }) } } diff --git a/services/doctor/lfs.go b/services/doctor/lfs.go index 5f110b8f97..a90f394450 100644 --- a/services/doctor/lfs.go +++ b/services/doctor/lfs.go @@ -5,7 +5,7 @@ package doctor import ( "context" - "fmt" + "errors" "time" "code.gitea.io/gitea/modules/log" @@ -27,7 +27,7 @@ func init() { func garbageCollectLFSCheck(ctx context.Context, logger log.Logger, autofix bool) error { if !setting.LFS.StartServer { - return fmt.Errorf("LFS support is disabled") + return errors.New("LFS support is disabled") } if err := repository.GarbageCollectLFSMetaObjects(ctx, repository.GarbageCollectLFSMetaObjectsOptions{ diff --git a/services/doctor/storage.go b/services/doctor/storage.go index 3f3b562c37..77fc6d65df 100644 --- a/services/doctor/storage.go +++ b/services/doctor/storage.go @@ -121,7 +121,7 @@ func checkStorage(opts *checkStorageOptions) func(ctx context.Context, logger lo storer: storage.LFS, isOrphaned: func(path string, obj storage.Object, stat fs.FileInfo) (bool, error) { // The oid of an LFS stored object is the name but with all the path.Separators removed - oid := strings.ReplaceAll(path, "/", "") + oid := strings.ReplaceAll(strings.ReplaceAll(path, "\\", ""), "/", "") exists, err := git.ExistsLFSObject(ctx, oid) return !exists, err }, diff --git a/services/externalaccount/link.go b/services/externalaccount/link.go index d6e2ea7e94..ab853140cb 100644 --- a/services/externalaccount/link.go +++ b/services/externalaccount/link.go @@ -5,7 +5,7 @@ package externalaccount import ( "context" - "fmt" + "errors" user_model "code.gitea.io/gitea/models/user" @@ -23,7 +23,7 @@ type Store interface { func LinkAccountFromStore(ctx context.Context, store Store, user *user_model.User) error { gothUser := store.Get("linkAccountGothUser") if gothUser == nil { - return fmt.Errorf("not in LinkAccount session") + return errors.New("not in LinkAccount session") } return LinkAccountToUser(ctx, user, gothUser.(goth.User)) diff --git a/services/feed/feed.go b/services/feed/feed.go index 214e9b5765..38a4e25308 100644 --- a/services/feed/feed.go +++ b/services/feed/feed.go @@ -6,6 +6,7 @@ package feed import ( "context" "fmt" + "strconv" activities_model "code.gitea.io/gitea/models/activities" "code.gitea.io/gitea/models/db" @@ -86,7 +87,7 @@ func notifyWatchers(ctx context.Context, act *activities_model.Action, watchers return fmt.Errorf("count user feeds: %w", err) } - _ = cache.GetCache().Put(userFeedCacheKey(act.UserID), fmt.Sprintf("%d", total), setting.CacheService.TTLSeconds()) + _ = cache.GetCache().Put(userFeedCacheKey(act.UserID), strconv.FormatInt(total, 10), setting.CacheService.TTLSeconds()) } return nil diff --git a/services/feed/feed_test.go b/services/feed/feed_test.go index 243bc046b0..a3492938c8 100644 --- a/services/feed/feed_test.go +++ b/services/feed/feed_test.go @@ -30,7 +30,7 @@ func TestGetFeeds(t *testing.T) { assert.NoError(t, err) if assert.Len(t, actions, 1) { assert.EqualValues(t, 1, actions[0].ID) - assert.EqualValues(t, user.ID, actions[0].UserID) + assert.Equal(t, user.ID, actions[0].UserID) } assert.Equal(t, int64(1), count) @@ -107,7 +107,7 @@ func TestGetFeeds2(t *testing.T) { assert.Len(t, actions, 1) if assert.Len(t, actions, 1) { assert.EqualValues(t, 2, actions[0].ID) - assert.EqualValues(t, org.ID, actions[0].UserID) + assert.Equal(t, org.ID, actions[0].UserID) } assert.Equal(t, int64(1), count) diff --git a/services/gitdiff/git_diff_tree.go b/services/gitdiff/git_diff_tree.go index 035210a31d..ed94bfbfe4 100644 --- a/services/gitdiff/git_diff_tree.go +++ b/services/gitdiff/git_diff_tree.go @@ -6,6 +6,7 @@ package gitdiff import ( "bufio" "context" + "errors" "fmt" "io" "strconv" @@ -71,7 +72,7 @@ func runGitDiffTree(ctx context.Context, gitRepo *git.Repository, useMergeBase b func validateGitDiffTreeArguments(gitRepo *git.Repository, useMergeBase bool, baseSha, headSha string) (shouldUseMergeBase bool, resolvedBaseSha, resolvedHeadSha string, err error) { // if the head is empty its an error if headSha == "" { - return false, "", "", fmt.Errorf("headSha is empty") + return false, "", "", errors.New("headSha is empty") } // if the head commit doesn't exist its and error @@ -207,7 +208,7 @@ func parseGitDiffTreeLine(line string) (*DiffTreeRecord, error) { func statusFromLetter(rawStatus string) (status string, score uint8, err error) { if len(rawStatus) < 1 { - return "", 0, fmt.Errorf("empty status letter") + return "", 0, errors.New("empty status letter") } switch rawStatus[0] { case 'A': @@ -235,7 +236,7 @@ func statusFromLetter(rawStatus string) (status string, score uint8, err error) func tryParseStatusScore(rawStatus string) (uint8, error) { if len(rawStatus) < 2 { - return 0, fmt.Errorf("status score missing") + return 0, errors.New("status score missing") } score, err := strconv.ParseUint(rawStatus[1:], 10, 8) diff --git a/services/gitdiff/highlightdiff_test.go b/services/gitdiff/highlightdiff_test.go index c2584dc622..aebe38ae7c 100644 --- a/services/gitdiff/highlightdiff_test.go +++ b/services/gitdiff/highlightdiff_test.go @@ -38,15 +38,15 @@ func TestDiffWithHighlight(t *testing.T) { hcd.placeholderTokenMap['O'], hcd.placeholderTokenMap['C'] = "", "" assert.Equal(t, "", string(hcd.recoverOneDiff("OC"))) assert.Equal(t, "", string(hcd.recoverOneDiff("O"))) - assert.Equal(t, "", string(hcd.recoverOneDiff("C"))) + assert.Empty(t, string(hcd.recoverOneDiff("C"))) }) } func TestDiffWithHighlightPlaceholder(t *testing.T) { hcd := newHighlightCodeDiff() output := hcd.diffLineWithHighlight(DiffLineDel, "a='\U00100000'", "a='\U0010FFFD''") - assert.Equal(t, "", hcd.placeholderTokenMap[0x00100000]) - assert.Equal(t, "", hcd.placeholderTokenMap[0x0010FFFD]) + assert.Empty(t, hcd.placeholderTokenMap[0x00100000]) + assert.Empty(t, hcd.placeholderTokenMap[0x0010FFFD]) expected := fmt.Sprintf(`a='%s'`, "\U00100000") assert.Equal(t, expected, string(output)) diff --git a/services/issue/comments.go b/services/issue/comments.go index 46f92f7cd2..10c81198d5 100644 --- a/services/issue/comments.go +++ b/services/issue/comments.go @@ -5,6 +5,7 @@ package issue import ( "context" + "errors" "fmt" "code.gitea.io/gitea/models/db" @@ -22,7 +23,7 @@ import ( // CreateRefComment creates a commit reference comment to issue. func CreateRefComment(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, issue *issues_model.Issue, content, commitSHA string) error { if len(commitSHA) == 0 { - return fmt.Errorf("cannot create reference with empty commit SHA") + return errors.New("cannot create reference with empty commit SHA") } if user_model.IsUserBlockedBy(ctx, doer, issue.PosterID, repo.OwnerID) { diff --git a/services/issue/issue_test.go b/services/issue/issue_test.go index 8806cec0e7..b3df8191e1 100644 --- a/services/issue/issue_test.go +++ b/services/issue/issue_test.go @@ -24,8 +24,8 @@ func TestGetRefEndNamesAndURLs(t *testing.T) { repoLink := "/foo/bar" endNames, urls := GetRefEndNamesAndURLs(issues, repoLink) - assert.EqualValues(t, map[int64]string{1: "branch1", 2: "tag1", 3: "c0ffee"}, endNames) - assert.EqualValues(t, map[int64]string{ + assert.Equal(t, map[int64]string{1: "branch1", 2: "tag1", 3: "c0ffee"}, endNames) + assert.Equal(t, map[int64]string{ 1: repoLink + "/src/branch/branch1", 2: repoLink + "/src/tag/tag1", 3: repoLink + "/src/commit/c0ffee", diff --git a/services/issue/milestone.go b/services/issue/milestone.go index beb6f131a9..afca70794d 100644 --- a/services/issue/milestone.go +++ b/services/issue/milestone.go @@ -5,6 +5,7 @@ package issue import ( "context" + "errors" "fmt" "code.gitea.io/gitea/models/db" @@ -21,7 +22,7 @@ func changeMilestoneAssign(ctx context.Context, doer *user_model.User, issue *is return fmt.Errorf("HasMilestoneByRepoID: %w", err) } if !has { - return fmt.Errorf("HasMilestoneByRepoID: issue doesn't exist") + return errors.New("HasMilestoneByRepoID: issue doesn't exist") } } diff --git a/services/issue/suggestion_test.go b/services/issue/suggestion_test.go index 84cfd520ac..a5b39d27bb 100644 --- a/services/issue/suggestion_test.go +++ b/services/issue/suggestion_test.go @@ -51,7 +51,7 @@ func Test_Suggestion(t *testing.T) { for _, issue := range issues { issueIndexes = append(issueIndexes, issue.Index) } - assert.EqualValues(t, testCase.expectedIndexes, issueIndexes) + assert.Equal(t, testCase.expectedIndexes, issueIndexes) }) } } diff --git a/services/lfs/server.go b/services/lfs/server.go index 1e7608b781..0a99287ed9 100644 --- a/services/lfs/server.go +++ b/services/lfs/server.go @@ -572,15 +572,15 @@ func handleLFSToken(ctx stdCtx.Context, tokenSHA string, target *repo_model.Repo claims, claimsOk := token.Claims.(*Claims) if !token.Valid || !claimsOk { - return nil, fmt.Errorf("invalid token claim") + return nil, errors.New("invalid token claim") } if claims.RepoID != target.ID { - return nil, fmt.Errorf("invalid token claim") + return nil, errors.New("invalid token claim") } if mode == perm_model.AccessModeWrite && claims.Op != "upload" { - return nil, fmt.Errorf("invalid token claim") + return nil, errors.New("invalid token claim") } u, err := user_model.GetUserByID(ctx, claims.UserID) @@ -593,12 +593,12 @@ func handleLFSToken(ctx stdCtx.Context, tokenSHA string, target *repo_model.Repo func parseToken(ctx stdCtx.Context, authorization string, target *repo_model.Repository, mode perm_model.AccessMode) (*user_model.User, error) { if authorization == "" { - return nil, fmt.Errorf("no token") + return nil, errors.New("no token") } parts := strings.SplitN(authorization, " ", 2) if len(parts) != 2 { - return nil, fmt.Errorf("no token") + return nil, errors.New("no token") } tokenSHA := parts[1] switch strings.ToLower(parts[0]) { @@ -607,7 +607,7 @@ func parseToken(ctx stdCtx.Context, authorization string, target *repo_model.Rep case "token": return handleLFSToken(ctx, tokenSHA, target, mode) } - return nil, fmt.Errorf("token not found") + return nil, errors.New("token not found") } func requireAuth(ctx *context.Context) { diff --git a/services/mailer/mail.go b/services/mailer/mail.go index f7e5b0c9f0..aa51cbdbcf 100644 --- a/services/mailer/mail.go +++ b/services/mailer/mail.go @@ -8,6 +8,7 @@ import ( "bytes" "context" "encoding/base64" + "errors" "fmt" "html/template" "io" @@ -117,7 +118,7 @@ func (b64embedder *mailAttachmentBase64Embedder) AttachmentSrcToBase64DataURI(ct attachmentUUID, ok = strings.CutPrefix(parsedSrc.RepoSubPath, "/attachments/") } if !ok { - return "", fmt.Errorf("not an attachment") + return "", errors.New("not an attachment") } } attachment, err := repo_model.GetAttachmentByUUID(ctx, attachmentUUID) @@ -126,10 +127,10 @@ func (b64embedder *mailAttachmentBase64Embedder) AttachmentSrcToBase64DataURI(ct } if attachment.RepoID != b64embedder.repo.ID { - return "", fmt.Errorf("attachment does not belong to the repository") + return "", errors.New("attachment does not belong to the repository") } if attachment.Size+b64embedder.estimateSize > b64embedder.maxSize { - return "", fmt.Errorf("total embedded images exceed max limit") + return "", errors.New("total embedded images exceed max limit") } fr, err := storage.Attachments.Open(attachment.RelativePath()) @@ -146,7 +147,7 @@ func (b64embedder *mailAttachmentBase64Embedder) AttachmentSrcToBase64DataURI(ct mimeType := typesniffer.DetectContentType(content) if !mimeType.IsImage() { - return "", fmt.Errorf("not an image") + return "", errors.New("not an image") } encoded := base64.StdEncoding.EncodeToString(content) diff --git a/services/mailer/mail_team_invite.go b/services/mailer/mail_team_invite.go index 1fbade7e23..f4aa788dec 100644 --- a/services/mailer/mail_team_invite.go +++ b/services/mailer/mail_team_invite.go @@ -6,6 +6,7 @@ package mailer import ( "bytes" "context" + "errors" "fmt" "net/url" @@ -38,10 +39,10 @@ func MailTeamInvite(ctx context.Context, inviter *user_model.User, team *org_mod if err != nil && !user_model.IsErrUserNotExist(err) { return err } else if user != nil && user.ProhibitLogin { - return fmt.Errorf("login is prohibited for the invited user") + return errors.New("login is prohibited for the invited user") } - inviteRedirect := url.QueryEscape(fmt.Sprintf("/org/invite/%s", invite.Token)) + inviteRedirect := url.QueryEscape("/org/invite/" + invite.Token) inviteURL := fmt.Sprintf("%suser/sign_up?redirect_to=%s", setting.AppURL, inviteRedirect) if (err == nil && user != nil) || setting.Service.DisableRegistration || setting.Service.AllowOnlyExternalRegistration { diff --git a/services/mailer/mail_test.go b/services/mailer/mail_test.go index 6aced705f3..7a47cf3876 100644 --- a/services/mailer/mail_test.go +++ b/services/mailer/mail_test.go @@ -467,7 +467,7 @@ func TestFromDisplayName(t *testing.T) { t.Run(tc.userDisplayName, func(t *testing.T) { user := &user_model.User{FullName: tc.userDisplayName, Name: "tmp"} got := fromDisplayName(user) - assert.EqualValues(t, tc.fromDisplayName, got) + assert.Equal(t, tc.fromDisplayName, got) }) } @@ -484,7 +484,7 @@ func TestFromDisplayName(t *testing.T) { setting.Domain = oldDomain }() - assert.EqualValues(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"})) + assert.Equal(t, "Mister X (by Code IT on [code.it])", fromDisplayName(&user_model.User{FullName: "Mister X", Name: "tmp"})) }) } diff --git a/services/mailer/sender/smtp.go b/services/mailer/sender/smtp.go index c53c3da997..8dc1b40b74 100644 --- a/services/mailer/sender/smtp.go +++ b/services/mailer/sender/smtp.go @@ -5,6 +5,7 @@ package sender import ( "crypto/tls" + "errors" "fmt" "io" "net" @@ -99,7 +100,7 @@ func (s *SMTPSender) Send(from string, to []string, msg io.WriterTo) error { canAuth, options := client.Extension("AUTH") if len(opts.User) > 0 { if !canAuth { - return fmt.Errorf("SMTP server does not support AUTH, but credentials provided") + return errors.New("SMTP server does not support AUTH, but credentials provided") } var auth smtp.Auth diff --git a/services/mailer/sender/smtp_auth.go b/services/mailer/sender/smtp_auth.go index 260b12437b..c60e0dbfbb 100644 --- a/services/mailer/sender/smtp_auth.go +++ b/services/mailer/sender/smtp_auth.go @@ -4,6 +4,7 @@ package sender import ( + "errors" "fmt" "github.com/Azure/go-ntlmssp" @@ -60,7 +61,7 @@ func (a *ntlmAuth) Start(server *smtp.ServerInfo) (string, []byte, error) { func (a *ntlmAuth) Next(fromServer []byte, more bool) ([]byte, error) { if more { if len(fromServer) == 0 { - return nil, fmt.Errorf("ntlm ChallengeMessage is empty") + return nil, errors.New("ntlm ChallengeMessage is empty") } authenticateMessage, err := ntlmssp.ProcessChallenge(fromServer, a.username, a.password, a.domainNeeded) return authenticateMessage, err diff --git a/services/markup/renderhelper_codepreview.go b/services/markup/renderhelper_codepreview.go index d638af7ff0..28d1120984 100644 --- a/services/markup/renderhelper_codepreview.go +++ b/services/markup/renderhelper_codepreview.go @@ -6,7 +6,7 @@ package markup import ( "bufio" "context" - "fmt" + "errors" "html/template" "strings" @@ -38,7 +38,7 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie webCtx := gitea_context.GetWebContext(ctx) if webCtx == nil { - return "", fmt.Errorf("context is not a web context") + return "", errors.New("context is not a web context") } doer := webCtx.Doer @@ -68,7 +68,7 @@ func renderRepoFileCodePreview(ctx context.Context, opts markup.RenderCodePrevie } if blob.Size() > setting.UI.MaxDisplayFileSize { - return "", fmt.Errorf("file is too large") + return "", errors.New("file is too large") } dataRc, err := blob.DataAsync() diff --git a/services/markup/renderhelper_issueicontitle.go b/services/markup/renderhelper_issueicontitle.go index fd8f9d43fa..27b5595fa9 100644 --- a/services/markup/renderhelper_issueicontitle.go +++ b/services/markup/renderhelper_issueicontitle.go @@ -5,6 +5,7 @@ package markup import ( "context" + "errors" "fmt" "html/template" @@ -20,7 +21,7 @@ import ( func renderRepoIssueIconTitle(ctx context.Context, opts markup.RenderIssueIconTitleOptions) (_ template.HTML, err error) { webCtx := gitea_context.GetWebContext(ctx) if webCtx == nil { - return "", fmt.Errorf("context is not a web context") + return "", errors.New("context is not a web context") } textIssueIndex := fmt.Sprintf("(#%d)", opts.IssueIndex) diff --git a/services/markup/renderhelper_mention_test.go b/services/markup/renderhelper_mention_test.go index d05fbb6fba..d54ab13a48 100644 --- a/services/markup/renderhelper_mention_test.go +++ b/services/markup/renderhelper_mention_test.go @@ -37,7 +37,7 @@ func TestRenderHelperMention(t *testing.T) { assert.False(t, FormalRenderHelperFuncs().IsUsernameMentionable(t.Context(), userNoSuch)) // when using web context, use user.IsUserVisibleToViewer to check - req, err := http.NewRequest("GET", "/", nil) + req, err := http.NewRequest(http.MethodGet, "/", nil) assert.NoError(t, err) base := gitea_context.NewBaseContextForTest(httptest.NewRecorder(), req) giteaCtx := gitea_context.NewWebContext(base, &contexttest.MockRender{}, nil) diff --git a/services/migrations/codebase.go b/services/migrations/codebase.go index 880dd21497..240c7bcdc9 100644 --- a/services/migrations/codebase.go +++ b/services/migrations/codebase.go @@ -134,7 +134,7 @@ func (d *CodebaseDownloader) callAPI(ctx context.Context, endpoint string, param u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return err } diff --git a/services/migrations/codecommit.go b/services/migrations/codecommit.go index c45f9e5943..4b2634ef8a 100644 --- a/services/migrations/codecommit.go +++ b/services/migrations/codecommit.go @@ -5,7 +5,7 @@ package migrations import ( "context" - "fmt" + "errors" "net/url" "strconv" "strings" @@ -42,13 +42,13 @@ func (c *CodeCommitDownloaderFactory) New(ctx context.Context, opts base.Migrate hostElems := strings.Split(u.Host, ".") if len(hostElems) != 4 { - return nil, fmt.Errorf("cannot get the region from clone URL") + return nil, errors.New("cannot get the region from clone URL") } region := hostElems[1] pathElems := strings.Split(u.Path, "/") if len(pathElems) == 0 { - return nil, fmt.Errorf("cannot get the repo name from clone URL") + return nil, errors.New("cannot get the repo name from clone URL") } repoName := pathElems[len(pathElems)-1] diff --git a/services/migrations/gitea_downloader.go b/services/migrations/gitea_downloader.go index f92f318293..5d48d2f003 100644 --- a/services/migrations/gitea_downloader.go +++ b/services/migrations/gitea_downloader.go @@ -298,7 +298,7 @@ func (g *GiteaDownloader) convertGiteaRelease(rel *gitea_sdk.Release) *base.Rele } // FIXME: for a private download? - req, err := http.NewRequest("GET", assetDownloadURL, nil) + req, err := http.NewRequest(http.MethodGet, assetDownloadURL, nil) if err != nil { return nil, err } diff --git a/services/migrations/gitea_downloader_test.go b/services/migrations/gitea_downloader_test.go index da56120065..bb1760e889 100644 --- a/services/migrations/gitea_downloader_test.go +++ b/services/migrations/gitea_downloader_test.go @@ -47,7 +47,7 @@ func TestGiteaDownloadRepo(t *testing.T) { topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) sort.Strings(topics) - assert.EqualValues(t, []string{"ci", "gitea", "migration", "test"}, topics) + assert.Equal(t, []string{"ci", "gitea", "migration", "test"}, topics) labels, err := downloader.GetLabels(ctx) assert.NoError(t, err) @@ -134,7 +134,7 @@ func TestGiteaDownloadRepo(t *testing.T) { assert.NoError(t, err) assert.True(t, isEnd) assert.Len(t, issues, 7) - assert.EqualValues(t, "open", issues[0].State) + assert.Equal(t, "open", issues[0].State) issues, isEnd, err = downloader.GetIssues(ctx, 3, 2) assert.NoError(t, err) diff --git a/services/migrations/gitea_uploader.go b/services/migrations/gitea_uploader.go index b17cc3ce41..cd5af39910 100644 --- a/services/migrations/gitea_uploader.go +++ b/services/migrations/gitea_uploader.go @@ -1017,7 +1017,7 @@ func (g *GiteaLocalUploader) remapLocalUser(ctx context.Context, source user_mod func (g *GiteaLocalUploader) remapExternalUser(ctx context.Context, source user_model.ExternalUserMigrated) (userid int64, err error) { userid, ok := g.userMap[source.GetExternalID()] if !ok { - userid, err = user_model.GetUserIDByExternalUserID(ctx, g.gitServiceType.Name(), fmt.Sprintf("%d", source.GetExternalID())) + userid, err = user_model.GetUserIDByExternalUserID(ctx, g.gitServiceType.Name(), strconv.FormatInt(source.GetExternalID(), 10)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) return 0, err diff --git a/services/migrations/gitea_uploader_test.go b/services/migrations/gitea_uploader_test.go index f52d4157c8..1970c0550c 100644 --- a/services/migrations/gitea_uploader_test.go +++ b/services/migrations/gitea_uploader_test.go @@ -64,7 +64,7 @@ func TestGiteaUploadRepo(t *testing.T) { 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) + assert.Equal(t, repo_model.RepositoryReady, repo.Status) milestones, err := db.Find[issues_model.Milestone](db.DefaultContext, issues_model.FindMilestoneOptions{ RepoID: repo.ID, @@ -152,7 +152,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // The externalID matches a known user but the name does not match, @@ -163,7 +163,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // The externalID and externalName match an existing user, everything @@ -174,7 +174,7 @@ func TestGiteaUploadRemapLocalUser(t *testing.T) { uploader.userMap = make(map[int64]int64) err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, user.ID, target.GetUserID()) + assert.Equal(t, user.ID, target.GetUserID()) } func TestGiteaUploadRemapExternalUser(t *testing.T) { @@ -202,7 +202,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { target := repo_model.Release{} err := uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, doer.ID, target.GetUserID()) + assert.Equal(t, doer.ID, target.GetUserID()) // // Link the external ID to an existing user @@ -225,7 +225,7 @@ func TestGiteaUploadRemapExternalUser(t *testing.T) { target = repo_model.Release{} err = uploader.remapUser(ctx, &source, &target) assert.NoError(t, err) - assert.EqualValues(t, linkedUser.ID, target.GetUserID()) + assert.Equal(t, linkedUser.ID, target.GetUserID()) } func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { @@ -239,7 +239,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { assert.NoError(t, git.InitRepository(git.DefaultContext, fromRepo.RepoPath(), false, fromRepo.ObjectFormatName)) err := git.NewCommand("symbolic-ref").AddDynamicArguments("HEAD", git.BranchPrefix+baseRef).Run(git.DefaultContext, &git.RunOpts{Dir: fromRepo.RepoPath()}) assert.NoError(t, err) - assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", fromRepo.RepoPath())), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(fromRepo.RepoPath(), "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+fromRepo.RepoPath()), 0o644)) assert.NoError(t, git.AddChanges(fromRepo.RepoPath(), true)) signature := git.Signature{ Email: "test@example.com", @@ -287,7 +287,7 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { })) _, _, err = git.NewCommand("checkout", "-b").AddDynamicArguments(forkHeadRef).RunStdString(git.DefaultContext, &git.RunOpts{Dir: forkRepo.RepoPath()}) assert.NoError(t, err) - assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte(fmt.Sprintf("# branch2 %s", forkRepo.RepoPath())), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(forkRepo.RepoPath(), "README.md"), []byte("# branch2 "+forkRepo.RepoPath()), 0o644)) assert.NoError(t, git.AddChanges(forkRepo.RepoPath(), true)) assert.NoError(t, git.CommitChanges(forkRepo.RepoPath(), git.CommitChangesOptions{ Committer: &signature, @@ -508,14 +508,14 @@ func TestGiteaUploadUpdateGitForPullRequest(t *testing.T) { head, err := uploader.updateGitForPullRequest(ctx, &testCase.pr) assert.NoError(t, err) - assert.EqualValues(t, testCase.head, head) + assert.Equal(t, testCase.head, head) log.Info(stopMark) logFiltered, logStopped := logChecker.Check(5 * time.Second) assert.True(t, logStopped) if len(testCase.logFilter) > 0 { - assert.EqualValues(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter) + assert.Equal(t, testCase.logFiltered, logFiltered, "for log message filters: %v", testCase.logFilter) } }) } diff --git a/services/migrations/github.go b/services/migrations/github.go index b00d6ed27f..e512ebc24a 100644 --- a/services/migrations/github.go +++ b/services/migrations/github.go @@ -358,7 +358,7 @@ func (g *GithubDownloaderV3) convertGithubRelease(ctx context.Context, rel *gith } g.waitAndPickClient(ctx) - req, err := http.NewRequestWithContext(ctx, "GET", redirectURL, nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, redirectURL, nil) if err != nil { return nil, err } diff --git a/services/migrations/gitlab.go b/services/migrations/gitlab.go index 4bed8e2f6c..a19a04bc44 100644 --- a/services/migrations/gitlab.go +++ b/services/migrations/gitlab.go @@ -341,7 +341,7 @@ func (g *GitlabDownloader) convertGitlabRelease(ctx context.Context, rel *gitlab return io.NopCloser(strings.NewReader(link.URL)), nil } - req, err := http.NewRequest("GET", link.URL, nil) + req, err := http.NewRequest(http.MethodGet, link.URL, nil) if err != nil { return nil, err } diff --git a/services/migrations/gitlab_test.go b/services/migrations/gitlab_test.go index 52f5827dfe..73a1b6a276 100644 --- a/services/migrations/gitlab_test.go +++ b/services/migrations/gitlab_test.go @@ -50,7 +50,7 @@ func TestGitlabDownloadRepo(t *testing.T) { topics, err := downloader.GetTopics(ctx) assert.NoError(t, err) assert.Len(t, topics, 2) - assert.EqualValues(t, []string{"migration", "test"}, topics) + assert.Equal(t, []string{"migration", "test"}, topics) milestones, err := downloader.GetMilestones(ctx) assert.NoError(t, err) @@ -501,7 +501,7 @@ func TestAwardsToReactions(t *testing.T) { assert.NoError(t, json.Unmarshal([]byte(testResponse), &awards)) reactions := downloader.awardsToReactions(awards) - assert.EqualValues(t, []*base.Reaction{ + assert.Equal(t, []*base.Reaction{ { UserName: "lafriks", UserID: 1241334, @@ -593,7 +593,7 @@ func TestNoteToComment(t *testing.T) { for i, note := range notes { actualComment := *downloader.convertNoteToComment(17, ¬e) - assert.EqualValues(t, actualComment, comments[i]) + assert.Equal(t, actualComment, comments[i]) } } diff --git a/services/migrations/migrate.go b/services/migrations/migrate.go index 5dda12286f..961abe16f4 100644 --- a/services/migrations/migrate.go +++ b/services/migrations/migrate.go @@ -6,6 +6,7 @@ package migrations import ( "context" + "errors" "fmt" "net" "net/url" @@ -211,7 +212,7 @@ func migrateRepository(ctx context.Context, doer *user_model.User, downloader ba if cloneURL.Scheme == "file" || cloneURL.Scheme == "" { if cloneAddrURL.Scheme != "file" && cloneAddrURL.Scheme != "" { - return fmt.Errorf("repo info has changed from external to local filesystem") + return errors.New("repo info has changed from external to local filesystem") } } diff --git a/services/migrations/onedev.go b/services/migrations/onedev.go index 4ce35dd12e..e052cba0cc 100644 --- a/services/migrations/onedev.go +++ b/services/migrations/onedev.go @@ -128,7 +128,7 @@ func (d *OneDevDownloader) callAPI(ctx context.Context, endpoint string, paramet u.RawQuery = query.Encode() } - req, err := http.NewRequestWithContext(ctx, "GET", u.String(), nil) + req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil) if err != nil { return err } diff --git a/services/mirror/mirror.go b/services/mirror/mirror.go index e029bbb1d6..7fb7fabb75 100644 --- a/services/mirror/mirror.go +++ b/services/mirror/mirror.go @@ -5,7 +5,7 @@ package mirror import ( "context" - "fmt" + "errors" repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/modules/log" @@ -29,7 +29,7 @@ func doMirrorSync(ctx context.Context, req *SyncRequest) { } } -var errLimit = fmt.Errorf("reached limit") +var errLimit = errors.New("reached limit") // Update checks and updates mirror repositories. func Update(ctx context.Context, pullLimit, pushLimit int) error { @@ -68,7 +68,7 @@ func Update(ctx context.Context, pullLimit, pushLimit int) error { // Check we've not been cancelled select { case <-ctx.Done(): - return fmt.Errorf("aborted") + return errors.New("aborted") default: } diff --git a/services/mirror/mirror_pull.go b/services/mirror/mirror_pull.go index fa5b9934ec..c43a4ef04a 100644 --- a/services/mirror/mirror_pull.go +++ b/services/mirror/mirror_pull.go @@ -437,7 +437,7 @@ func runSync(ctx context.Context, m *repo_model.Mirror) ([]*mirrorSyncResult, bo } for _, branch := range branches { - cache.Remove(m.Repo.GetCommitsCountCacheKey(branch.Name, true)) + cache.Remove(m.Repo.GetCommitsCountCacheKey(branch, true)) } m.UpdatedUnix = timeutil.TimeStampNow() diff --git a/services/mirror/mirror_pull_test.go b/services/mirror/mirror_pull_test.go index 67ef37c954..97859be5b0 100644 --- a/services/mirror/mirror_pull_test.go +++ b/services/mirror/mirror_pull_test.go @@ -24,45 +24,45 @@ func Test_parseRemoteUpdateOutput(t *testing.T) { ` results := parseRemoteUpdateOutput(output, "origin") assert.Len(t, results, 10) - assert.EqualValues(t, "refs/tags/v0.1.8", results[0].refName.String()) - assert.EqualValues(t, gitShortEmptySha, results[0].oldCommitID) - assert.EqualValues(t, "", results[0].newCommitID) + assert.Equal(t, "refs/tags/v0.1.8", results[0].refName.String()) + assert.Equal(t, gitShortEmptySha, results[0].oldCommitID) + assert.Empty(t, results[0].newCommitID) - assert.EqualValues(t, "refs/heads/master", results[1].refName.String()) - assert.EqualValues(t, gitShortEmptySha, results[1].oldCommitID) - assert.EqualValues(t, "", results[1].newCommitID) + assert.Equal(t, "refs/heads/master", results[1].refName.String()) + assert.Equal(t, gitShortEmptySha, results[1].oldCommitID) + assert.Empty(t, results[1].newCommitID) - assert.EqualValues(t, "refs/heads/test1", results[2].refName.String()) - assert.EqualValues(t, "", results[2].oldCommitID) - assert.EqualValues(t, gitShortEmptySha, results[2].newCommitID) + assert.Equal(t, "refs/heads/test1", results[2].refName.String()) + assert.Empty(t, results[2].oldCommitID) + assert.Equal(t, gitShortEmptySha, results[2].newCommitID) - assert.EqualValues(t, "refs/tags/tag1", results[3].refName.String()) - assert.EqualValues(t, "", results[3].oldCommitID) - assert.EqualValues(t, gitShortEmptySha, results[3].newCommitID) + assert.Equal(t, "refs/tags/tag1", results[3].refName.String()) + assert.Empty(t, results[3].oldCommitID) + assert.Equal(t, gitShortEmptySha, results[3].newCommitID) - assert.EqualValues(t, "refs/heads/test2", results[4].refName.String()) - assert.EqualValues(t, "f895a1e", results[4].oldCommitID) - assert.EqualValues(t, "957a993", results[4].newCommitID) + assert.Equal(t, "refs/heads/test2", results[4].refName.String()) + assert.Equal(t, "f895a1e", results[4].oldCommitID) + assert.Equal(t, "957a993", results[4].newCommitID) - assert.EqualValues(t, "refs/heads/test3", results[5].refName.String()) - assert.EqualValues(t, "957a993", results[5].oldCommitID) - assert.EqualValues(t, "a87ba5f", results[5].newCommitID) + assert.Equal(t, "refs/heads/test3", results[5].refName.String()) + assert.Equal(t, "957a993", results[5].oldCommitID) + assert.Equal(t, "a87ba5f", results[5].newCommitID) - assert.EqualValues(t, "refs/pull/26595/head", results[6].refName.String()) - assert.EqualValues(t, gitShortEmptySha, results[6].oldCommitID) - assert.EqualValues(t, "", results[6].newCommitID) + assert.Equal(t, "refs/pull/26595/head", results[6].refName.String()) + assert.Equal(t, gitShortEmptySha, results[6].oldCommitID) + assert.Empty(t, results[6].newCommitID) - assert.EqualValues(t, "refs/pull/26595/merge", results[7].refName.String()) - assert.EqualValues(t, gitShortEmptySha, results[7].oldCommitID) - assert.EqualValues(t, "", results[7].newCommitID) + assert.Equal(t, "refs/pull/26595/merge", results[7].refName.String()) + assert.Equal(t, gitShortEmptySha, results[7].oldCommitID) + assert.Empty(t, results[7].newCommitID) - assert.EqualValues(t, "refs/pull/25873/head", results[8].refName.String()) - assert.EqualValues(t, "e0639e38fb", results[8].oldCommitID) - assert.EqualValues(t, "6db2410489", results[8].newCommitID) + assert.Equal(t, "refs/pull/25873/head", results[8].refName.String()) + assert.Equal(t, "e0639e38fb", results[8].oldCommitID) + assert.Equal(t, "6db2410489", results[8].newCommitID) - assert.EqualValues(t, "refs/pull/25873/merge", results[9].refName.String()) - assert.EqualValues(t, "1c97ebc746", results[9].oldCommitID) - assert.EqualValues(t, "976d27d52f", results[9].newCommitID) + assert.Equal(t, "refs/pull/25873/merge", results[9].refName.String()) + assert.Equal(t, "1c97ebc746", results[9].oldCommitID) + assert.Equal(t, "976d27d52f", results[9].newCommitID) } func Test_checkRecoverableSyncError(t *testing.T) { diff --git a/services/oauth2_provider/access_token.go b/services/oauth2_provider/access_token.go index 5cb6fb64c5..52a73c9572 100644 --- a/services/oauth2_provider/access_token.go +++ b/services/oauth2_provider/access_token.go @@ -7,6 +7,7 @@ import ( "context" "fmt" "slices" + "strconv" "strings" auth "code.gitea.io/gitea/models/auth" @@ -177,7 +178,7 @@ func NewAccessTokenResponse(ctx context.Context, grant *auth.OAuth2Grant, server ExpiresAt: jwt.NewNumericDate(expirationDate.AsTime()), Issuer: setting.AppURL, Audience: []string{app.ClientID}, - Subject: fmt.Sprint(grant.UserID), + Subject: strconv.FormatInt(grant.UserID, 10), }, Nonce: grant.Nonce, } diff --git a/services/oauth2_provider/jwtsigningkey.go b/services/oauth2_provider/jwtsigningkey.go index 6c668db463..3bc4f49410 100644 --- a/services/oauth2_provider/jwtsigningkey.go +++ b/services/oauth2_provider/jwtsigningkey.go @@ -31,7 +31,7 @@ type ErrInvalidAlgorithmType struct { } func (err ErrInvalidAlgorithmType) Error() string { - return fmt.Sprintf("JWT signing algorithm is not supported: %s", err.Algorithm) + return "JWT signing algorithm is not supported: " + err.Algorithm } // JWTSigningKey represents a algorithm/key pair to sign JWTs diff --git a/services/oauth2_provider/token.go b/services/oauth2_provider/token.go index b71b11906e..383bcdb3eb 100644 --- a/services/oauth2_provider/token.go +++ b/services/oauth2_provider/token.go @@ -4,6 +4,7 @@ package oauth2_provider //nolint import ( + "errors" "fmt" "time" @@ -44,12 +45,12 @@ func ParseToken(jwtToken string, signingKey JWTSigningKey) (*Token, error) { return nil, err } if !parsedToken.Valid { - return nil, fmt.Errorf("invalid token") + return nil, errors.New("invalid token") } var token *Token var ok bool if token, ok = parsedToken.Claims.(*Token); !ok || !parsedToken.Valid { - return nil, fmt.Errorf("invalid token") + return nil, errors.New("invalid token") } return token, nil } diff --git a/services/org/team_test.go b/services/org/team_test.go index 3791776e46..a7070fadb0 100644 --- a/services/org/team_test.go +++ b/services/org/team_test.go @@ -88,7 +88,7 @@ func TestUpdateTeam(t *testing.T) { assert.True(t, strings.HasPrefix(team.Description, "A long description!")) access := unittest.AssertExistsAndLoadBean(t, &access_model.Access{UserID: 4, RepoID: 3}) - assert.EqualValues(t, perm.AccessModeAdmin, access.Mode) + assert.Equal(t, perm.AccessModeAdmin, access.Mode) unittest.CheckConsistencyFor(t, &organization.Team{ID: team.ID}) } diff --git a/services/org/user_test.go b/services/org/user_test.go index 96d1a1c8ca..c61d600d90 100644 --- a/services/org/user_test.go +++ b/services/org/user_test.go @@ -53,7 +53,7 @@ func TestRemoveOrgUser(t *testing.T) { assert.NoError(t, RemoveOrgUser(db.DefaultContext, org, user)) unittest.AssertNotExistsBean(t, &organization.OrgUser{OrgID: org.ID, UID: user.ID}) org = unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: org.ID}) - assert.EqualValues(t, expectedNumMembers, org.NumMembers) + assert.Equal(t, expectedNumMembers, org.NumMembers) } org3 := unittest.AssertExistsAndLoadBean(t, &organization.Organization{ID: 3}) diff --git a/services/packages/alpine/repository.go b/services/packages/alpine/repository.go index 27e6391980..277c188874 100644 --- a/services/packages/alpine/repository.go +++ b/services/packages/alpine/repository.go @@ -290,7 +290,7 @@ func buildPackagesIndex(ctx context.Context, ownerID int64, repoVersion *package privPem, _ := pem.Decode([]byte(priv)) if privPem == nil { - return fmt.Errorf("failed to decode private key pem") + return errors.New("failed to decode private key pem") } privKey, err := x509.ParsePKCS1PrivateKey(privPem.Bytes) diff --git a/services/packages/arch/repository.go b/services/packages/arch/repository.go index a12af82ba5..438bb10837 100644 --- a/services/packages/arch/repository.go +++ b/services/packages/arch/repository.go @@ -13,6 +13,7 @@ import ( "fmt" "io" "os" + "strconv" "strings" packages_model "code.gitea.io/gitea/models/packages" @@ -372,8 +373,8 @@ func writeDescription(tw *tar.Writer, opts *entryOptions) error { {"MD5SUM", opts.Blob.HashMD5}, {"SHA256SUM", opts.Blob.HashSHA256}, {"PGPSIG", opts.Signature}, - {"CSIZE", fmt.Sprintf("%d", opts.Blob.Size)}, - {"ISIZE", fmt.Sprintf("%d", opts.FileMetadata.InstalledSize)}, + {"CSIZE", strconv.FormatInt(opts.Blob.Size, 10)}, + {"ISIZE", strconv.FormatInt(opts.FileMetadata.InstalledSize, 10)}, {"NAME", opts.Package.Name}, {"BASE", opts.FileMetadata.Base}, {"ARCH", opts.FileMetadata.Architecture}, @@ -382,7 +383,7 @@ func writeDescription(tw *tar.Writer, opts *entryOptions) error { {"URL", opts.VersionMetadata.ProjectURL}, {"LICENSE", strings.Join(opts.VersionMetadata.Licenses, "\n")}, {"GROUPS", strings.Join(opts.FileMetadata.Groups, "\n")}, - {"BUILDDATE", fmt.Sprintf("%d", opts.FileMetadata.BuildDate)}, + {"BUILDDATE", strconv.FormatInt(opts.FileMetadata.BuildDate, 10)}, {"PACKAGER", opts.FileMetadata.Packager}, {"PROVIDES", strings.Join(opts.FileMetadata.Provides, "\n")}, {"REPLACES", strings.Join(opts.FileMetadata.Replaces, "\n")}, diff --git a/services/packages/auth.go b/services/packages/auth.go index 4526a8e303..6e87643e29 100644 --- a/services/packages/auth.go +++ b/services/packages/auth.go @@ -4,6 +4,7 @@ package packages import ( + "errors" "fmt" "net/http" "strings" @@ -58,7 +59,7 @@ func ParseAuthorizationRequest(req *http.Request) (*PackageMeta, error) { parts := strings.SplitN(h, " ", 2) if len(parts) != 2 { log.Error("split token failed: %s", h) - return nil, fmt.Errorf("split token failed") + return nil, errors.New("split token failed") } return ParseAuthorizationToken(parts[1]) @@ -77,7 +78,7 @@ func ParseAuthorizationToken(tokenStr string) (*PackageMeta, error) { c, ok := token.Claims.(*packageClaims) if !token.Valid || !ok { - return nil, fmt.Errorf("invalid token claim") + return nil, errors.New("invalid token claim") } return &c.PackageMeta, nil diff --git a/services/packages/cargo/index.go b/services/packages/cargo/index.go index 0c8a98c40f..decb224b85 100644 --- a/services/packages/cargo/index.go +++ b/services/packages/cargo/index.go @@ -247,7 +247,7 @@ func createOrUpdateConfigFile(ctx context.Context, repo *repo_model.Repository, "Initialize Cargo Config", func(t *files_service.TemporaryUploadRepository) error { var b bytes.Buffer - err := json.NewEncoder(&b).Encode(BuildConfig(owner, setting.Service.RequireSignInView || owner.Visibility != structs.VisibleTypePublic || repo.IsPrivate)) + err := json.NewEncoder(&b).Encode(BuildConfig(owner, setting.Service.RequireSignInViewStrict || owner.Visibility != structs.VisibleTypePublic || repo.IsPrivate)) if err != nil { return err } diff --git a/services/packages/rpm/repository.go b/services/packages/rpm/repository.go index a7d196c15c..5027021c52 100644 --- a/services/packages/rpm/repository.go +++ b/services/packages/rpm/repository.go @@ -408,7 +408,6 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs [] files = append(files, f) } } - packageVersion := fmt.Sprintf("%s-%s", pd.FileMetadata.Version, pd.FileMetadata.Release) packages = append(packages, &Package{ Type: "rpm", Name: pd.Package.Name, @@ -437,7 +436,7 @@ func buildPrimary(ctx context.Context, pv *packages_model.PackageVersion, pfs [] Archive: pd.FileMetadata.ArchiveSize, }, Location: Location{ - Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, packageVersion, pd.FileMetadata.Architecture, pd.Package.Name, packageVersion, pd.FileMetadata.Architecture), + Href: fmt.Sprintf("package/%s/%s/%s/%s-%s.%s.rpm", pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture, pd.Package.Name, pd.Version.Version, pd.FileMetadata.Architecture), }, Format: Format{ License: pd.VersionMetadata.License, diff --git a/services/projects/issue.go b/services/projects/issue.go index 090d19d2f4..590fe960d5 100644 --- a/services/projects/issue.go +++ b/services/projects/issue.go @@ -5,7 +5,7 @@ package project import ( "context" - "fmt" + "errors" "code.gitea.io/gitea/models/db" issues_model "code.gitea.io/gitea/models/issues" @@ -29,7 +29,7 @@ func MoveIssuesOnProjectColumn(ctx context.Context, doer *user_model.User, colum return err } if int(count) != len(sortedIssueIDs) { - return fmt.Errorf("all issues have to be added to a project first") + return errors.New("all issues have to be added to a project first") } issues, err := issues_model.GetIssuesByIDs(ctx, issueIDs) diff --git a/services/projects/issue_test.go b/services/projects/issue_test.go index b6f0b1dae1..e76d31e757 100644 --- a/services/projects/issue_test.go +++ b/services/projects/issue_test.go @@ -130,7 +130,7 @@ func Test_Projects(t *testing.T) { }) assert.NoError(t, err) assert.Len(t, projects, 1) - assert.EqualValues(t, project1.ID, projects[0].ID) + assert.Equal(t, project1.ID, projects[0].ID) t.Run("Authenticated user", func(t *testing.T) { columnIssues, err := LoadIssuesFromProject(db.DefaultContext, projects[0], &issues_model.IssuesOptions{ diff --git a/services/pull/check.go b/services/pull/check.go index 9b159891d7..b036970fbf 100644 --- a/services/pull/check.go +++ b/services/pull/check.go @@ -400,7 +400,7 @@ func Init() error { prPatchCheckerQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "pr_patch_checker", handler) if prPatchCheckerQueue == nil { - return fmt.Errorf("unable to create pr_patch_checker queue") + return errors.New("unable to create pr_patch_checker queue") } go graceful.GetManager().RunWithCancel(prPatchCheckerQueue) diff --git a/services/pull/check_test.go b/services/pull/check_test.go index 5508a70f45..6d85ac158e 100644 --- a/services/pull/check_test.go +++ b/services/pull/check_test.go @@ -51,7 +51,7 @@ func TestPullRequest_AddToTaskQueue(t *testing.T) { select { case id := <-idChan: - assert.EqualValues(t, pr.ID, id) + assert.Equal(t, pr.ID, id) case <-time.After(time.Second): assert.FailNow(t, "Timeout: nothing was added to pullRequestQueue") } diff --git a/services/pull/merge.go b/services/pull/merge.go index 1e1ca55bc1..9804d8aac1 100644 --- a/services/pull/merge.go +++ b/services/pull/merge.go @@ -6,6 +6,7 @@ package pull import ( "context" + "errors" "fmt" "os" "path/filepath" @@ -59,7 +60,7 @@ func getMergeMessage(ctx context.Context, baseGitRepo *git.Repository, pr *issue issueReference = "!" } - reviewedOn := fmt.Sprintf("Reviewed-on: %s", httplib.MakeAbsoluteURL(ctx, pr.Issue.Link())) + reviewedOn := "Reviewed-on: " + httplib.MakeAbsoluteURL(ctx, pr.Issue.Link()) reviewedBy := pr.GetApprovers(ctx) if mergeStyle != "" { @@ -621,13 +622,13 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use objectFormat := git.ObjectFormatFromName(pr.BaseRepo.ObjectFormatName) if len(commitID) != objectFormat.FullLength() { - return fmt.Errorf("Wrong commit ID") + return errors.New("Wrong commit ID") } commit, err := baseGitRepo.GetCommit(commitID) if err != nil { if git.IsErrNotExist(err) { - return fmt.Errorf("Wrong commit ID") + return errors.New("Wrong commit ID") } return err } @@ -638,14 +639,14 @@ func MergedManually(ctx context.Context, pr *issues_model.PullRequest, doer *use return err } if !ok { - return fmt.Errorf("Wrong commit ID") + return errors.New("Wrong commit ID") } var merged bool if merged, err = SetMerged(ctx, pr, commitID, timeutil.TimeStamp(commit.Author.When.Unix()), doer, issues_model.PullRequestStatusManuallyMerged); err != nil { return err } else if !merged { - return fmt.Errorf("SetMerged failed") + return errors.New("SetMerged failed") } return nil }) diff --git a/services/pull/merge_squash.go b/services/pull/merge_squash.go index 076189fd7a..72660cd3c5 100644 --- a/services/pull/merge_squash.go +++ b/services/pull/merge_squash.go @@ -66,8 +66,8 @@ func doMergeStyleSquash(ctx *mergeContext, message string) error { if setting.Repository.PullRequest.AddCoCommitterTrailers && ctx.committer.String() != sig.String() { // add trailer - if !strings.Contains(message, fmt.Sprintf("Co-authored-by: %s", sig.String())) { - message += fmt.Sprintf("\nCo-authored-by: %s", sig.String()) + if !strings.Contains(message, "Co-authored-by: "+sig.String()) { + message += "\nCo-authored-by: " + sig.String() } message += fmt.Sprintf("\nCo-committed-by: %s\n", sig.String()) } diff --git a/services/pull/patch.go b/services/pull/patch.go index 29f2f992ab..68f3f02669 100644 --- a/services/pull/patch.go +++ b/services/pull/patch.go @@ -134,7 +134,7 @@ type errMergeConflict struct { } func (e *errMergeConflict) Error() string { - return fmt.Sprintf("conflict detected at: %s", e.filename) + return "conflict detected at: " + e.filename } func attemptMerge(ctx context.Context, file *unmergedFile, tmpBasePath string, filesToRemove *[]string, filesToAdd *[]git.IndexObjectInfo) error { diff --git a/services/pull/pull.go b/services/pull/pull.go index 4641d4ac40..13cbb40110 100644 --- a/services/pull/pull.go +++ b/services/pull/pull.go @@ -763,7 +763,7 @@ func CloseRepoBranchesPulls(ctx context.Context, doer *user_model.User, repo *re var errs []error for _, branch := range branches { - prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(ctx, repo.ID, branch.Name) + prs, err := issues_model.GetUnmergedPullRequestsByHeadInfo(ctx, repo.ID, branch) if err != nil { return err } diff --git a/services/pull/review.go b/services/pull/review.go index 78723a58ae..5c80e7b338 100644 --- a/services/pull/review.go +++ b/services/pull/review.go @@ -395,7 +395,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, } if review.Type != issues_model.ReviewTypeApprove && review.Type != issues_model.ReviewTypeReject { - return nil, fmt.Errorf("not need to dismiss this review because it's type is not Approve or change request") + return nil, errors.New("not need to dismiss this review because it's type is not Approve or change request") } // load data for notify @@ -405,7 +405,7 @@ func DismissReview(ctx context.Context, reviewID, repoID int64, message string, // Check if the review's repoID is the one we're currently expecting. if review.Issue.RepoID != repoID { - return nil, fmt.Errorf("reviews's repository is not the same as the one we expect") + return nil, errors.New("reviews's repository is not the same as the one we expect") } issue := review.Issue diff --git a/services/pull/update.go b/services/pull/update.go index 3e00dd4e65..5cc5e2b134 100644 --- a/services/pull/update.go +++ b/services/pull/update.go @@ -5,6 +5,7 @@ package pull import ( "context" + "errors" "fmt" git_model "code.gitea.io/gitea/models/git" @@ -23,7 +24,7 @@ import ( func Update(ctx context.Context, pr *issues_model.PullRequest, doer *user_model.User, message string, rebase bool) error { if pr.Flow == issues_model.PullRequestFlowAGit { // TODO: update of agit flow pull request's head branch is unsupported - return fmt.Errorf("update of agit flow pull request's head branch is unsupported") + return errors.New("update of agit flow pull request's head branch is unsupported") } releaser, err := globallock.Lock(ctx, getPullWorkingLockKey(pr.ID)) diff --git a/services/release/release_test.go b/services/release/release_test.go index 95a54832b9..36a9f667d6 100644 --- a/services/release/release_test.go +++ b/services/release/release_test.go @@ -250,9 +250,9 @@ func TestRelease_Update(t *testing.T) { assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, []string{attach.UUID}, nil, nil)) assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) assert.Len(t, release.Attachments, 1) - assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID) - assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID) - assert.EqualValues(t, attach.Name, release.Attachments[0].Name) + assert.Equal(t, attach.UUID, release.Attachments[0].UUID) + assert.Equal(t, release.ID, release.Attachments[0].ReleaseID) + assert.Equal(t, attach.Name, release.Attachments[0].Name) // update the attachment name assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, nil, nil, map[string]string{ @@ -261,9 +261,9 @@ func TestRelease_Update(t *testing.T) { release.Attachments = nil assert.NoError(t, repo_model.GetReleaseAttachments(db.DefaultContext, release)) assert.Len(t, release.Attachments, 1) - assert.EqualValues(t, attach.UUID, release.Attachments[0].UUID) - assert.EqualValues(t, release.ID, release.Attachments[0].ReleaseID) - assert.EqualValues(t, "test2.txt", release.Attachments[0].Name) + assert.Equal(t, attach.UUID, release.Attachments[0].UUID) + assert.Equal(t, release.ID, release.Attachments[0].ReleaseID) + assert.Equal(t, "test2.txt", release.Attachments[0].Name) // delete the attachment assert.NoError(t, UpdateRelease(db.DefaultContext, user, gitRepo, release, nil, []string{attach.UUID}, nil)) diff --git a/services/repository/archiver/archiver.go b/services/repository/archiver/archiver.go index d39acc080d..a657e3884c 100644 --- a/services/repository/archiver/archiver.go +++ b/services/repository/archiver/archiver.go @@ -44,7 +44,7 @@ type ErrUnknownArchiveFormat struct { // Error implements error func (err ErrUnknownArchiveFormat) Error() string { - return fmt.Sprintf("unknown format: %s", err.RequestNameType) + return "unknown format: " + err.RequestNameType } // Is implements error @@ -60,7 +60,7 @@ type RepoRefNotFoundError struct { // Error implements error. func (e RepoRefNotFoundError) Error() string { - return fmt.Sprintf("unrecognized repository reference: %s", e.RefShortName) + return "unrecognized repository reference: " + e.RefShortName } func (e RepoRefNotFoundError) Is(err error) bool { diff --git a/services/repository/archiver/archiver_test.go b/services/repository/archiver/archiver_test.go index 522f90558a..87324ad38c 100644 --- a/services/repository/archiver/archiver_test.go +++ b/services/repository/archiver/archiver_test.go @@ -33,7 +33,7 @@ func TestArchive_Basic(t *testing.T) { bogusReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) - assert.EqualValues(t, firstCommit+".zip", bogusReq.GetArchiveName()) + assert.Equal(t, firstCommit+".zip", bogusReq.GetArchiveName()) // Check a series of bogus requests. // Step 1, valid commit with a bad extension. @@ -54,12 +54,12 @@ func TestArchive_Basic(t *testing.T) { bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "master.zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) - assert.EqualValues(t, "master.zip", bogusReq.GetArchiveName()) + assert.Equal(t, "master.zip", bogusReq.GetArchiveName()) bogusReq, err = NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, "test/archive.zip") assert.NoError(t, err) assert.NotNil(t, bogusReq) - assert.EqualValues(t, "test-archive.zip", bogusReq.GetArchiveName()) + assert.Equal(t, "test-archive.zip", bogusReq.GetArchiveName()) // Now two valid requests, firstCommit with valid extensions. zipReq, err := NewRequest(ctx.Repo.Repository.ID, ctx.Repo.GitRepo, firstCommit+".zip") diff --git a/services/repository/avatar_test.go b/services/repository/avatar_test.go index bea820e85f..2dc5173eec 100644 --- a/services/repository/avatar_test.go +++ b/services/repository/avatar_test.go @@ -59,7 +59,7 @@ func TestDeleteAvatar(t *testing.T) { err = DeleteAvatar(db.DefaultContext, repo) assert.NoError(t, err) - assert.Equal(t, "", repo.Avatar) + assert.Empty(t, repo.Avatar) } func TestGenerateAvatar(t *testing.T) { diff --git a/services/repository/branch.go b/services/repository/branch.go index 8804778bd5..94c47ffdc4 100644 --- a/services/repository/branch.go +++ b/services/repository/branch.go @@ -303,7 +303,7 @@ func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames, // For other batches, it will hit optimization 4. if len(branchNames) != len(commitIDs) { - return fmt.Errorf("branchNames and commitIDs length not match") + return errors.New("branchNames and commitIDs length not match") } return db.WithTx(ctx, func(ctx context.Context) error { diff --git a/services/repository/contributors_graph_test.go b/services/repository/contributors_graph_test.go index 6db93f6a64..7d32b1c931 100644 --- a/services/repository/contributors_graph_test.go +++ b/services/repository/contributors_graph_test.go @@ -38,14 +38,14 @@ func TestRepository_ContributorsGraph(t *testing.T) { keys = append(keys, k) } slices.Sort(keys) - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "ethantkoenig@gmail.com", "jimmy.praet@telenet.be", "jon@allspice.io", "total", // generated summary }, keys) - assert.EqualValues(t, &ContributorData{ + assert.Equal(t, &ContributorData{ Name: "Ethan Koenig", AvatarLink: "/assets/img/avatar_default.png", TotalCommits: 1, @@ -58,7 +58,7 @@ func TestRepository_ContributorsGraph(t *testing.T) { }, }, }, data["ethantkoenig@gmail.com"]) - assert.EqualValues(t, &ContributorData{ + assert.Equal(t, &ContributorData{ Name: "Total", AvatarLink: "", TotalCommits: 3, diff --git a/services/repository/files/cherry_pick.go b/services/repository/files/cherry_pick.go index 0e069fb2ce..6818bb343d 100644 --- a/services/repository/files/cherry_pick.go +++ b/services/repository/files/cherry_pick.go @@ -5,6 +5,7 @@ package files import ( "context" + "errors" "fmt" "strings" @@ -100,7 +101,7 @@ func CherryPick(ctx context.Context, repo *repo_model.Repository, doer *user_mod } if conflict { - return nil, fmt.Errorf("failed to merge due to conflicts") + return nil, errors.New("failed to merge due to conflicts") } treeHash, err := t.WriteTree(ctx) diff --git a/services/repository/files/content.go b/services/repository/files/content.go index 0ab7422ce2..e23cd1abce 100644 --- a/services/repository/files/content.go +++ b/services/repository/files/content.go @@ -188,6 +188,14 @@ func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref }, } + // GitHub doesn't have these fields in the response, but we could follow other similar APIs to name them + // https://docs.github.com/en/rest/commits/commits?apiVersion=2022-11-28#list-commits + if lastCommit.Committer != nil { + contentsResponse.LastCommitterDate = lastCommit.Committer.When + } + if lastCommit.Author != nil { + contentsResponse.LastAuthorDate = lastCommit.Author.When + } // Now populate the rest of the ContentsResponse based on entry type if entry.IsRegular() || entry.IsExecutable() { contentsResponse.Type = string(ContentTypeRegular) diff --git a/services/repository/files/content_test.go b/services/repository/files/content_test.go index 7cb46c0bb6..e066f30cba 100644 --- a/services/repository/files/content_test.go +++ b/services/repository/files/content_test.go @@ -5,6 +5,7 @@ package files import ( "testing" + "time" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/gitrepo" @@ -30,18 +31,20 @@ func getExpectedReadmeContentsResponse() *api.ContentsResponse { gitURL := "https://try.gitea.io/api/v1/repos/user2/repo1/git/blobs/" + sha downloadURL := "https://try.gitea.io/user2/repo1/raw/branch/master/" + treePath return &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f", - LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: "4b4851ad51df6a7d9f25c979345979eaeb5b349f", + LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", + LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -67,13 +70,13 @@ func TestGetContents(t *testing.T) { t.Run("Get README.md contents with GetContents(ctx, )", func(t *testing.T) { fileContentResponse, err := GetContents(ctx, ctx.Repo.Repository, treePath, ref, false) - assert.EqualValues(t, expectedContentsResponse, fileContentResponse) + assert.Equal(t, expectedContentsResponse, fileContentResponse) assert.NoError(t, err) }) t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContents(ctx, )", func(t *testing.T) { fileContentResponse, err := GetContents(ctx, ctx.Repo.Repository, treePath, "", false) - assert.EqualValues(t, expectedContentsResponse, fileContentResponse) + assert.Equal(t, expectedContentsResponse, fileContentResponse) assert.NoError(t, err) }) } diff --git a/services/repository/files/diff_test.go b/services/repository/files/diff_test.go index a8514791cc..ae702e4189 100644 --- a/services/repository/files/diff_test.go +++ b/services/repository/files/diff_test.go @@ -118,7 +118,7 @@ func TestGetDiffPreview(t *testing.T) { assert.NoError(t, err) bs, err := json.Marshal(diff) assert.NoError(t, err) - assert.EqualValues(t, string(expectedBs), string(bs)) + assert.Equal(t, string(expectedBs), string(bs)) }) t.Run("empty branch, same results", func(t *testing.T) { @@ -128,7 +128,7 @@ func TestGetDiffPreview(t *testing.T) { assert.NoError(t, err) bs, err := json.Marshal(diff) assert.NoError(t, err) - assert.EqualValues(t, expectedBs, bs) + assert.Equal(t, expectedBs, bs) }) } diff --git a/services/repository/files/file.go b/services/repository/files/file.go index 2caa1b4946..a8ad5889cb 100644 --- a/services/repository/files/file.go +++ b/services/repository/files/file.go @@ -5,6 +5,7 @@ package files import ( "context" + "errors" "fmt" "net/url" "strings" @@ -62,10 +63,10 @@ func GetFileResponseFromFilesResponse(filesResponse *api.FilesResponse, index in // GetFileCommitResponse Constructs a FileCommitResponse from a Commit object func GetFileCommitResponse(repo *repo_model.Repository, commit *git.Commit) (*api.FileCommitResponse, error) { if repo == nil { - return nil, fmt.Errorf("repo cannot be nil") + return nil, errors.New("repo cannot be nil") } if commit == nil { - return nil, fmt.Errorf("commit cannot be nil") + return nil, errors.New("commit cannot be nil") } commitURL, _ := url.Parse(repo.APIURL() + "/git/commits/" + url.PathEscape(commit.ID.String())) commitTreeURL, _ := url.Parse(repo.APIURL() + "/git/trees/" + url.PathEscape(commit.Tree.ID.String())) diff --git a/services/repository/files/file_test.go b/services/repository/files/file_test.go index 52c0574883..7cb79d7ebf 100644 --- a/services/repository/files/file_test.go +++ b/services/repository/files/file_test.go @@ -5,6 +5,7 @@ package files import ( "testing" + "time" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/gitrepo" @@ -20,14 +21,14 @@ func TestCleanUploadFileName(t *testing.T) { name := "this/is/test" cleanName := CleanUploadFileName(name) expectedCleanName := name - assert.EqualValues(t, expectedCleanName, cleanName) + assert.Equal(t, expectedCleanName, cleanName) }) t.Run("Clean a .git path", func(t *testing.T) { name := "this/is/test/.git" cleanName := CleanUploadFileName(name) expectedCleanName := "" - assert.EqualValues(t, expectedCleanName, cleanName) + assert.Equal(t, expectedCleanName, cleanName) }) } @@ -42,18 +43,20 @@ func getExpectedFileResponse() *api.FileResponse { downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: sha, - LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: sha, + LastCommitSHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d", + LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -116,5 +119,5 @@ func TestGetFileResponseFromCommit(t *testing.T) { fileResponse, err := GetFileResponseFromCommit(ctx, repo, commit, branch, treePath) assert.NoError(t, err) - assert.EqualValues(t, expectedFileResponse, fileResponse) + assert.Equal(t, expectedFileResponse, fileResponse) } diff --git a/services/repository/files/patch.go b/services/repository/files/patch.go index 1941adb86a..5fbf748206 100644 --- a/services/repository/files/patch.go +++ b/services/repository/files/patch.go @@ -12,7 +12,6 @@ import ( repo_model "code.gitea.io/gitea/models/repo" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/git" - "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/util" @@ -62,29 +61,26 @@ func (opts *ApplyDiffPatchOptions) Validate(ctx context.Context, repo *repo_mode opts.NewBranch = opts.OldBranch } - gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo) - if err != nil { - return err - } - defer closer.Close() - // oldBranch must exist for this operation - if _, err := gitRepo.GetBranch(opts.OldBranch); err != nil { + if exist, err := git_model.IsBranchExist(ctx, repo.ID, opts.OldBranch); err != nil { return err + } else if !exist { + return git_model.ErrBranchNotExist{ + BranchName: opts.OldBranch, + } } // A NewBranch can be specified for the patch to be applied to. // Check to make sure the branch does not already exist, otherwise we can't proceed. // If we aren't branching to a new branch, make sure user can commit to the given branch if opts.NewBranch != opts.OldBranch { - existingBranch, err := gitRepo.GetBranch(opts.NewBranch) - if existingBranch != nil { + exist, err := git_model.IsBranchExist(ctx, repo.ID, opts.NewBranch) + if err != nil { + return err + } else if exist { return git_model.ErrBranchAlreadyExists{ BranchName: opts.NewBranch, } } - if err != nil && !git.IsErrBranchNotExist(err) { - return err - } } else { protectedBranch, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repo.ID, opts.OldBranch) if err != nil { diff --git a/services/repository/files/temp_repo.go b/services/repository/files/temp_repo.go index d2c70a7a34..1969676ab4 100644 --- a/services/repository/files/temp_repo.go +++ b/services/repository/files/temp_repo.go @@ -6,6 +6,7 @@ package files import ( "bytes" "context" + "errors" "fmt" "io" "os" @@ -414,7 +415,7 @@ func (t *TemporaryUploadRepository) DiffIndex(ctx context.Context) (*gitdiff.Dif // GetBranchCommit Gets the commit object of the given branch func (t *TemporaryUploadRepository) GetBranchCommit(branch string) (*git.Commit, error) { if t.gitRepo == nil { - return nil, fmt.Errorf("repository has not been cloned") + return nil, errors.New("repository has not been cloned") } return t.gitRepo.GetBranchCommit(branch) } @@ -422,7 +423,7 @@ func (t *TemporaryUploadRepository) GetBranchCommit(branch string) (*git.Commit, // GetCommit Gets the commit object of the given commit ID func (t *TemporaryUploadRepository) GetCommit(commitID string) (*git.Commit, error) { if t.gitRepo == nil { - return nil, fmt.Errorf("repository has not been cloned") + return nil, errors.New("repository has not been cloned") } return t.gitRepo.GetCommit(commitID) } diff --git a/services/repository/files/tree.go b/services/repository/files/tree.go index 9142416347..faeb85a046 100644 --- a/services/repository/files/tree.go +++ b/services/repository/files/tree.go @@ -6,12 +6,14 @@ package files import ( "context" "fmt" + "html/template" "net/url" "path" "sort" "strings" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" @@ -140,8 +142,13 @@ func entryModeString(entryMode git.EntryMode) string { } type TreeViewNode struct { - EntryName string `json:"entryName"` - EntryMode string `json:"entryMode"` + EntryName string `json:"entryName"` + EntryMode string `json:"entryMode"` + EntryIcon template.HTML `json:"entryIcon"` + EntryIconOpen template.HTML `json:"entryIconOpen,omitempty"` + + SymLinkedToMode string `json:"symLinkedToMode,omitempty"` // TODO: for the EntryMode="symlink" + FullPath string `json:"fullPath"` SubmoduleURL string `json:"submoduleUrl,omitempty"` Children []*TreeViewNode `json:"children,omitempty"` @@ -151,13 +158,28 @@ func (node *TreeViewNode) sortLevel() int { return util.Iif(node.EntryMode == "tree" || node.EntryMode == "commit", 0, 1) } -func newTreeViewNodeFromEntry(ctx context.Context, commit *git.Commit, parentDir string, entry *git.TreeEntry) *TreeViewNode { +func newTreeViewNodeFromEntry(ctx context.Context, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, parentDir string, entry *git.TreeEntry) *TreeViewNode { node := &TreeViewNode{ EntryName: entry.Name(), EntryMode: entryModeString(entry.Mode()), FullPath: path.Join(parentDir, entry.Name()), } + if entry.IsLink() { + // TODO: symlink to a folder or a file, the icon differs + target, err := entry.FollowLink() + if err == nil { + _ = target.IsDir() + // if target.IsDir() { } else { } + } + } + + if node.EntryIcon == "" { + node.EntryIcon = fileicon.RenderEntryIcon(renderedIconPool, entry) + // TODO: no open icon support yet + // node.EntryIconOpen = fileicon.RenderEntryIconOpen(renderedIconPool, entry) + } + if node.EntryMode == "commit" { if subModule, err := commit.GetSubModule(node.FullPath); err != nil { log.Error("GetSubModule: %v", err) @@ -182,7 +204,7 @@ func sortTreeViewNodes(nodes []*TreeViewNode) { }) } -func listTreeNodes(ctx context.Context, commit *git.Commit, tree *git.Tree, treePath, subPath string) ([]*TreeViewNode, error) { +func listTreeNodes(ctx context.Context, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, tree *git.Tree, treePath, subPath string) ([]*TreeViewNode, error) { entries, err := tree.ListEntries() if err != nil { return nil, err @@ -191,14 +213,14 @@ func listTreeNodes(ctx context.Context, commit *git.Commit, tree *git.Tree, tree subPathDirName, subPathRemaining, _ := strings.Cut(subPath, "/") nodes := make([]*TreeViewNode, 0, len(entries)) for _, entry := range entries { - node := newTreeViewNodeFromEntry(ctx, commit, treePath, entry) + node := newTreeViewNodeFromEntry(ctx, renderedIconPool, commit, treePath, entry) nodes = append(nodes, node) if entry.IsDir() && subPathDirName == entry.Name() { subTreePath := treePath + "/" + node.EntryName if subTreePath[0] == '/' { subTreePath = subTreePath[1:] } - subNodes, err := listTreeNodes(ctx, commit, entry.Tree(), subTreePath, subPathRemaining) + subNodes, err := listTreeNodes(ctx, renderedIconPool, commit, entry.Tree(), subTreePath, subPathRemaining) if err != nil { log.Error("listTreeNodes: %v", err) } else { @@ -210,10 +232,10 @@ func listTreeNodes(ctx context.Context, commit *git.Commit, tree *git.Tree, tree return nodes, nil } -func GetTreeViewNodes(ctx context.Context, commit *git.Commit, treePath, subPath string) ([]*TreeViewNode, error) { +func GetTreeViewNodes(ctx context.Context, renderedIconPool *fileicon.RenderedIconPool, commit *git.Commit, treePath, subPath string) ([]*TreeViewNode, error) { entry, err := commit.GetTreeEntryByPath(treePath) if err != nil { return nil, err } - return listTreeNodes(ctx, commit, entry.Tree(), treePath, subPath) + return listTreeNodes(ctx, renderedIconPool, commit, entry.Tree(), treePath, subPath) } diff --git a/services/repository/files/tree_test.go b/services/repository/files/tree_test.go index 8ea54969ce..2657c49977 100644 --- a/services/repository/files/tree_test.go +++ b/services/repository/files/tree_test.go @@ -4,9 +4,11 @@ package files import ( + "html/template" "testing" "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/modules/fileicon" "code.gitea.io/gitea/modules/git" api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/services/contexttest" @@ -49,7 +51,7 @@ func TestGetTreeBySHA(t *testing.T) { TotalCount: 1, } - assert.EqualValues(t, expectedTree, tree) + assert.Equal(t, expectedTree, tree) } func TestGetTreeViewNodes(t *testing.T) { @@ -62,40 +64,51 @@ func TestGetTreeViewNodes(t *testing.T) { contexttest.LoadGitRepo(t, ctx) defer ctx.Repo.GitRepo.Close() - treeNodes, err := GetTreeViewNodes(ctx, ctx.Repo.Commit, "", "") + renderedIconPool := fileicon.NewRenderedIconPool() + mockIconForFile := func(id string) template.HTML { + return template.HTML(``) + } + mockIconForFolder := func(id string) template.HTML { + return template.HTML(``) + } + treeNodes, err := GetTreeViewNodes(ctx, renderedIconPool, ctx.Repo.Commit, "", "") assert.NoError(t, err) assert.Equal(t, []*TreeViewNode{ { EntryName: "docs", EntryMode: "tree", FullPath: "docs", + EntryIcon: mockIconForFolder(`svg-mfi-folder-docs`), }, }, treeNodes) - treeNodes, err = GetTreeViewNodes(ctx, ctx.Repo.Commit, "", "docs/README.md") + treeNodes, err = GetTreeViewNodes(ctx, renderedIconPool, ctx.Repo.Commit, "", "docs/README.md") assert.NoError(t, err) assert.Equal(t, []*TreeViewNode{ { EntryName: "docs", EntryMode: "tree", FullPath: "docs", + EntryIcon: mockIconForFolder(`svg-mfi-folder-docs`), Children: []*TreeViewNode{ { EntryName: "README.md", EntryMode: "blob", FullPath: "docs/README.md", + EntryIcon: mockIconForFile(`svg-mfi-readme`), }, }, }, }, treeNodes) - treeNodes, err = GetTreeViewNodes(ctx, ctx.Repo.Commit, "docs", "README.md") + treeNodes, err = GetTreeViewNodes(ctx, renderedIconPool, ctx.Repo.Commit, "docs", "README.md") assert.NoError(t, err) assert.Equal(t, []*TreeViewNode{ { EntryName: "README.md", EntryMode: "blob", FullPath: "docs/README.md", + EntryIcon: mockIconForFile(`svg-mfi-readme`), }, }, treeNodes) } diff --git a/services/repository/files/update.go b/services/repository/files/update.go index cade7ba2bf..3f6255e77a 100644 --- a/services/repository/files/update.go +++ b/services/repository/files/update.go @@ -107,8 +107,13 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use defer closer.Close() // oldBranch must exist for this operation - if _, err := gitRepo.GetBranch(opts.OldBranch); err != nil && !repo.IsEmpty { + if exist, err := git_model.IsBranchExist(ctx, repo.ID, opts.OldBranch); err != nil { return nil, err + } else if !exist && !repo.IsEmpty { + return nil, git_model.ErrBranchNotExist{ + RepoID: repo.ID, + BranchName: opts.OldBranch, + } } var treePaths []string @@ -145,15 +150,15 @@ func ChangeRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *use // Check to make sure the branch does not already exist, otherwise we can't proceed. // If we aren't branching to a new branch, make sure user can commit to the given branch if opts.NewBranch != opts.OldBranch { - existingBranch, err := gitRepo.GetBranch(opts.NewBranch) - if existingBranch != nil { + exist, err := git_model.IsBranchExist(ctx, repo.ID, opts.NewBranch) + if err != nil { + return nil, err + } + if exist { return nil, git_model.ErrBranchAlreadyExists{ BranchName: opts.NewBranch, } } - if err != nil && !git.IsErrBranchNotExist(err) { - return nil, err - } } else if err := VerifyBranchProtection(ctx, repo, doer, opts.OldBranch, treePaths); err != nil { return nil, err } diff --git a/services/repository/license_test.go b/services/repository/license_test.go index 9e74a268f5..eb897f3c03 100644 --- a/services/repository/license_test.go +++ b/services/repository/license_test.go @@ -4,7 +4,6 @@ package repository import ( - "fmt" "strings" "testing" @@ -45,7 +44,7 @@ func Test_detectLicense(t *testing.T) { assert.NoError(t, err) tests = append(tests, DetectLicenseTest{ - name: fmt.Sprintf("single license test: %s", licenseName), + name: "single license test: " + licenseName, arg: string(license), want: []string{licenseName}, }) diff --git a/services/repository/migrate.go b/services/repository/migrate.go index 9a5c6ffb0f..2a17e9acd9 100644 --- a/services/repository/migrate.go +++ b/services/repository/migrate.go @@ -142,12 +142,12 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User, if !repo.IsEmpty { if len(repo.DefaultBranch) == 0 { // Try to get HEAD branch and set it as default branch. - headBranch, err := gitRepo.GetHEADBranch() + headBranchName, err := git.GetDefaultBranch(ctx, repoPath) if err != nil { return repo, fmt.Errorf("GetHEADBranch: %w", err) } - if headBranch != nil { - repo.DefaultBranch = headBranch.Name + if headBranchName != "" { + repo.DefaultBranch = headBranchName } } diff --git a/services/repository/push.go b/services/repository/push.go index 6d3b9dd252..ba801ad019 100644 --- a/services/repository/push.go +++ b/services/repository/push.go @@ -66,7 +66,7 @@ func PushUpdates(opts []*repo_module.PushUpdateOptions) error { for _, opt := range opts { if opt.IsNewRef() && opt.IsDelRef() { - return fmt.Errorf("Old and new revisions are both NULL") + return errors.New("Old and new revisions are both NULL") } } @@ -385,7 +385,7 @@ func pushUpdateAddTags(ctx context.Context, repo *repo_model.Repository, gitRepo if err != nil { return fmt.Errorf("GetTag: %w", err) } - commit, err := tag.Commit(gitRepo) + commit, err := gitRepo.GetTagCommit(tag.Name) if err != nil { return fmt.Errorf("Commit: %w", err) } diff --git a/services/repository/repository.go b/services/repository/repository.go index fcc617979e..10f175d989 100644 --- a/services/repository/repository.go +++ b/services/repository/repository.go @@ -5,6 +5,7 @@ package repository import ( "context" + "errors" "fmt" "code.gitea.io/gitea/models/db" @@ -72,10 +73,10 @@ func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoN if ok, err := organization.CanCreateOrgRepo(ctx, owner.ID, authUser.ID); err != nil { return nil, err } else if !ok { - return nil, fmt.Errorf("cannot push-create repository for org") + return nil, errors.New("cannot push-create repository for org") } } else if authUser.ID != owner.ID { - return nil, fmt.Errorf("cannot push-create repository for another user") + return nil, errors.New("cannot push-create repository for another user") } } @@ -94,7 +95,7 @@ func PushCreateRepo(ctx context.Context, authUser, owner *user_model.User, repoN func Init(ctx context.Context) error { licenseUpdaterQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "repo_license_updater", repoLicenseUpdater) if licenseUpdaterQueue == nil { - return fmt.Errorf("unable to create repo_license_updater queue") + return errors.New("unable to create repo_license_updater queue") } go graceful.GetManager().RunWithCancel(licenseUpdaterQueue) diff --git a/services/repository/transfer.go b/services/repository/transfer.go index a589bc469d..4e44b90df2 100644 --- a/services/repository/transfer.go +++ b/services/repository/transfer.go @@ -20,10 +20,22 @@ import ( "code.gitea.io/gitea/modules/gitrepo" "code.gitea.io/gitea/modules/globallock" "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" notify_service "code.gitea.io/gitea/services/notify" ) +type LimitReachedError struct{ Limit int } + +func (LimitReachedError) Error() string { + return "Repository limit has been reached" +} + +func IsRepositoryLimitReached(err error) bool { + _, ok := err.(LimitReachedError) + return ok +} + func getRepoWorkingLockKey(repoID int64) string { return fmt.Sprintf("repo_working_%d", repoID) } @@ -49,6 +61,11 @@ func AcceptTransferOwnership(ctx context.Context, repo *repo_model.Repository, d return err } + if !doer.IsAdmin && !repoTransfer.Recipient.CanCreateRepo() { + limit := util.Iif(repoTransfer.Recipient.MaxRepoCreation >= 0, repoTransfer.Recipient.MaxRepoCreation, setting.Repository.MaxCreationLimit) + return LimitReachedError{Limit: limit} + } + if !repoTransfer.CanUserAcceptOrRejectTransfer(ctx, doer) { return util.ErrPermissionDenied } @@ -399,6 +416,11 @@ func StartRepositoryTransfer(ctx context.Context, doer, newOwner *user_model.Use return err } + if !doer.IsAdmin && !newOwner.CanCreateRepo() { + limit := util.Iif(newOwner.MaxRepoCreation >= 0, newOwner.MaxRepoCreation, setting.Repository.MaxCreationLimit) + return LimitReachedError{Limit: limit} + } + var isDirectTransfer bool oldOwnerName := repo.OwnerName diff --git a/services/repository/transfer_test.go b/services/repository/transfer_test.go index 16a8fb6e1e..bf71c7ca2e 100644 --- a/services/repository/transfer_test.go +++ b/services/repository/transfer_test.go @@ -1,4 +1,4 @@ -// Copyright 2019 The Gitea Authors. All rights reserved. +// Copyright 2025 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT package repository @@ -14,11 +14,14 @@ import ( repo_model "code.gitea.io/gitea/models/repo" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/util" "code.gitea.io/gitea/services/feed" notify_service "code.gitea.io/gitea/services/notify" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) var notifySync sync.Once @@ -125,3 +128,40 @@ func TestRepositoryTransfer(t *testing.T) { err = RejectRepositoryTransfer(db.DefaultContext, repo2, doer) assert.True(t, repo_model.IsErrNoPendingTransfer(err)) } + +// Test transfer rejections +func TestRepositoryTransferRejection(t *testing.T) { + require.NoError(t, unittest.PrepareTestDatabase()) + // Set limit to 0 repositories so no repositories can be transferred + defer test.MockVariableValue(&setting.Repository.MaxCreationLimit, 0)() + + // Admin case + doerAdmin := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}) + repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 5}) + + transfer, err := repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + require.NoError(t, err) + require.NotNil(t, transfer) + require.NoError(t, transfer.LoadRecipient(db.DefaultContext)) + + require.True(t, transfer.Recipient.CanCreateRepo()) // admin is not subject to limits + + // Administrator should not be affected by the limits so transfer should be successful + assert.NoError(t, AcceptTransferOwnership(db.DefaultContext, repo, doerAdmin)) + + // Non admin user case + doer := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 10}) + repo = unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 21}) + + transfer, err = repo_model.GetPendingRepositoryTransfer(db.DefaultContext, repo) + require.NoError(t, err) + require.NotNil(t, transfer) + require.NoError(t, transfer.LoadRecipient(db.DefaultContext)) + + require.False(t, transfer.Recipient.CanCreateRepo()) // regular user is subject to limits + + // Cannot accept because of the limit + err = AcceptTransferOwnership(db.DefaultContext, repo, doer) + assert.Error(t, err) + assert.True(t, IsRepositoryLimitReached(err)) +} diff --git a/services/task/task.go b/services/task/task.go index c90ee91270..105aee2a25 100644 --- a/services/task/task.go +++ b/services/task/task.go @@ -5,6 +5,7 @@ package task import ( "context" + "errors" "fmt" admin_model "code.gitea.io/gitea/models/admin" @@ -41,7 +42,7 @@ func Run(ctx context.Context, t *admin_model.Task) error { func Init() error { taskQueue = queue.CreateSimpleQueue(graceful.GetManager().ShutdownContext(), "task", handler) if taskQueue == nil { - return fmt.Errorf("unable to create task queue") + return errors.New("unable to create task queue") } go graceful.GetManager().RunWithCancel(taskQueue) return nil diff --git a/services/user/user_test.go b/services/user/user_test.go index 162a735cd4..28a0df8628 100644 --- a/services/user/user_test.go +++ b/services/user/user_test.go @@ -150,7 +150,7 @@ func TestRenameUser(t *testing.T) { redirectUID, err := user_model.LookupUserRedirect(db.DefaultContext, oldUsername) assert.NoError(t, err) - assert.EqualValues(t, user.ID, redirectUID) + assert.Equal(t, user.ID, redirectUID) unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerID: user.ID, OwnerName: user.Name}) }) diff --git a/services/webhook/deliver.go b/services/webhook/deliver.go index df32d5741e..e8e6ed19c1 100644 --- a/services/webhook/deliver.go +++ b/services/webhook/deliver.go @@ -10,6 +10,7 @@ import ( "crypto/sha256" "crypto/tls" "encoding/hex" + "errors" "fmt" "io" "net/http" @@ -41,7 +42,7 @@ func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook case http.MethodPost: switch w.ContentType { case webhook_model.ContentTypeJSON: - req, err = http.NewRequest("POST", w.URL, strings.NewReader(t.PayloadContent)) + req, err = http.NewRequest(http.MethodPost, w.URL, strings.NewReader(t.PayloadContent)) if err != nil { return nil, nil, err } @@ -52,7 +53,7 @@ func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook "payload": []string{t.PayloadContent}, } - req, err = http.NewRequest("POST", w.URL, strings.NewReader(forms.Encode())) + req, err = http.NewRequest(http.MethodPost, w.URL, strings.NewReader(forms.Encode())) if err != nil { return nil, nil, err } @@ -69,7 +70,7 @@ func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook vals := u.Query() vals["payload"] = []string{t.PayloadContent} u.RawQuery = vals.Encode() - req, err = http.NewRequest("GET", u.String(), nil) + req, err = http.NewRequest(http.MethodGet, u.String(), nil) if err != nil { return nil, nil, err } @@ -81,7 +82,7 @@ func newDefaultRequest(ctx context.Context, w *webhook_model.Webhook, t *webhook return nil, nil, err } url := fmt.Sprintf("%s/%s", w.URL, url.PathEscape(txnID)) - req, err = http.NewRequest("PUT", url, strings.NewReader(t.PayloadContent)) + req, err = http.NewRequest(http.MethodPut, url, strings.NewReader(t.PayloadContent)) if err != nil { return nil, nil, err } @@ -328,7 +329,7 @@ func Init() error { hookQueue = queue.CreateUniqueQueue(graceful.GetManager().ShutdownContext(), "webhook_sender", handler) if hookQueue == nil { - return fmt.Errorf("unable to create webhook_sender queue") + return errors.New("unable to create webhook_sender queue") } go graceful.GetManager().RunWithCancel(hookQueue) diff --git a/services/webhook/deliver_test.go b/services/webhook/deliver_test.go index 6a74b1455c..1d32d7b772 100644 --- a/services/webhook/deliver_test.go +++ b/services/webhook/deliver_test.go @@ -64,7 +64,7 @@ func TestWebhookProxy(t *testing.T) { } for _, tt := range tests { t.Run(tt.req, func(t *testing.T) { - req, err := http.NewRequest("POST", tt.req, nil) + req, err := http.NewRequest(http.MethodPost, tt.req, nil) require.NoError(t, err) u, err := webhookProxy(allowedHostMatcher)(req) @@ -91,7 +91,7 @@ func TestWebhookDeliverAuthorizationHeader(t *testing.T) { s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { assert.Equal(t, "/webhook", r.URL.Path) assert.Equal(t, "Bearer s3cr3t-t0ken", r.Header.Get("Authorization")) - w.WriteHeader(200) + w.WriteHeader(http.StatusOK) done <- struct{}{} })) t.Cleanup(s.Close) @@ -138,7 +138,7 @@ func TestWebhookDeliverHookTask(t *testing.T) { case "/webhook/66d222a5d6349e1311f551e50722d837e30fce98": // Version 1 assert.Equal(t, "push", r.Header.Get("X-GitHub-Event")) - assert.Equal(t, "", r.Header.Get("Content-Type")) + assert.Empty(t, r.Header.Get("Content-Type")) body, err := io.ReadAll(r.Body) assert.NoError(t, err) assert.Equal(t, `{"data": 42}`, string(body)) @@ -152,11 +152,11 @@ func TestWebhookDeliverHookTask(t *testing.T) { assert.Len(t, body, 2147) default: - w.WriteHeader(404) + w.WriteHeader(http.StatusNotFound) t.Fatalf("unexpected url path %s", r.URL.Path) return } - w.WriteHeader(200) + w.WriteHeader(http.StatusOK) done <- struct{}{} })) t.Cleanup(s.Close) diff --git a/services/webhook/dingtalk.go b/services/webhook/dingtalk.go index 5afca8d65a..ce907bf0cb 100644 --- a/services/webhook/dingtalk.go +++ b/services/webhook/dingtalk.go @@ -30,7 +30,7 @@ func (dc dingtalkConvertor) Create(p *api.CreatePayload) (DingtalkPayload, error refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s created", p.Repo.FullName, p.RefType, refName) - return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil + return createDingtalkPayload(title, title, "view ref "+refName, p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil } // Delete implements PayloadConvertor Delete method @@ -39,14 +39,14 @@ func (dc dingtalkConvertor) Delete(p *api.DeletePayload) (DingtalkPayload, error refName := git.RefName(p.Ref).ShortName() title := fmt.Sprintf("[%s] %s %s deleted", p.Repo.FullName, p.RefType, refName) - return createDingtalkPayload(title, title, fmt.Sprintf("view ref %s", refName), p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil + return createDingtalkPayload(title, title, "view ref "+refName, p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName)), nil } // Fork implements PayloadConvertor Fork method func (dc dingtalkConvertor) Fork(p *api.ForkPayload) (DingtalkPayload, error) { title := fmt.Sprintf("%s is forked to %s", p.Forkee.FullName, p.Repo.FullName) - return createDingtalkPayload(title, title, fmt.Sprintf("view forked repo %s", p.Repo.FullName), p.Repo.HTMLURL), nil + return createDingtalkPayload(title, title, "view forked repo "+p.Repo.FullName, p.Repo.HTMLURL), nil } // Push implements PayloadConvertor Push method diff --git a/services/webhook/discord.go b/services/webhook/discord.go index 0a7eb0b166..0e8a9aa67c 100644 --- a/services/webhook/discord.go +++ b/services/webhook/discord.go @@ -101,6 +101,13 @@ var ( redColor = color("ff3232") ) +// https://discord.com/developers/docs/resources/message#embed-object-embed-limits +// Discord has some limits in place for the embeds. +// According to some tests, there is no consistent limit for different character sets. +// For example: 4096 ASCII letters are allowed, but only 2490 emoji characters are allowed. +// To keep it simple, we currently truncate at 2000. +const discordDescriptionCharactersLimit = 2000 + type discordConvertor struct { Username string AvatarURL string @@ -313,7 +320,7 @@ func (d discordConvertor) createPayload(s *api.User, title, text, url string, co Embeds: []DiscordEmbed{ { Title: title, - Description: text, + Description: util.TruncateRunes(text, discordDescriptionCharactersLimit), URL: url, Color: color, Author: DiscordEmbedAuthor{ diff --git a/services/webhook/general.go b/services/webhook/general.go index c58f83354d..251659e75e 100644 --- a/services/webhook/general.go +++ b/services/webhook/general.go @@ -43,16 +43,16 @@ func getPullRequestInfo(p *api.PullRequestPayload) (title, link, by, operator, o case api.HookIssueAssigned: operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName) case api.HookIssueUnassigned: - operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName) + operateResult = p.Sender.UserName + " unassigned this for someone" case api.HookIssueMilestoned: operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.PullRequest.Milestone.ID) } link = p.PullRequest.HTMLURL - by = fmt.Sprintf("PullRequest by %s", p.PullRequest.Poster.UserName) + by = "PullRequest by " + p.PullRequest.Poster.UserName if len(assignStringList) > 0 { - assignees = fmt.Sprintf("Assignees: %s", strings.Join(assignStringList, ", ")) + assignees = "Assignees: " + strings.Join(assignStringList, ", ") } - operator = fmt.Sprintf("Operator: %s", p.Sender.UserName) + operator = "Operator: " + p.Sender.UserName return title, link, by, operator, operateResult, assignees } @@ -69,16 +69,16 @@ func getIssuesInfo(p *api.IssuePayload) (issueTitle, link, by, operator, operate case api.HookIssueAssigned: operateResult = fmt.Sprintf("%s assign this to %s", p.Sender.UserName, assignList[len(assignList)-1].UserName) case api.HookIssueUnassigned: - operateResult = fmt.Sprintf("%s unassigned this for someone", p.Sender.UserName) + operateResult = p.Sender.UserName + " unassigned this for someone" case api.HookIssueMilestoned: operateResult = fmt.Sprintf("%s/milestone/%d", p.Repository.HTMLURL, p.Issue.Milestone.ID) } link = p.Issue.HTMLURL - by = fmt.Sprintf("Issue by %s", p.Issue.Poster.UserName) + by = "Issue by " + p.Issue.Poster.UserName if len(assignStringList) > 0 { - assignees = fmt.Sprintf("Assignees: %s", strings.Join(assignStringList, ", ")) + assignees = "Assignees: " + strings.Join(assignStringList, ", ") } - operator = fmt.Sprintf("Operator: %s", p.Sender.UserName) + operator = "Operator: " + p.Sender.UserName return issueTitle, link, by, operator, operateResult, assignees } @@ -87,11 +87,11 @@ func getIssuesCommentInfo(p *api.IssueCommentPayload) (title, link, by, operator title = fmt.Sprintf("[Comment-%s #%d]: %s\n%s", p.Repository.FullName, p.Issue.Index, p.Action, p.Issue.Title) link = p.Issue.HTMLURL if p.IsPull { - by = fmt.Sprintf("PullRequest by %s", p.Issue.Poster.UserName) + by = "PullRequest by " + p.Issue.Poster.UserName } else { - by = fmt.Sprintf("Issue by %s", p.Issue.Poster.UserName) + by = "Issue by " + p.Issue.Poster.UserName } - operator = fmt.Sprintf("Operator: %s", p.Sender.UserName) + operator = "Operator: " + p.Sender.UserName return title, link, by, operator } @@ -135,7 +135,7 @@ func getIssuesPayloadInfo(p *api.IssuePayload, linkFormatter linkFormatter, with text = fmt.Sprintf("[%s] Issue milestone cleared: %s", repoLink, titleLink) } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } if p.Action == api.HookIssueOpened || p.Action == api.HookIssueEdited { @@ -200,7 +200,7 @@ func getPullRequestPayloadInfo(p *api.PullRequestPayload, linkFormatter linkForm text = fmt.Sprintf("[%s] Pull request review request removed: %s", repoLink, titleLink) } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+p.Sender.UserName, p.Sender.UserName) } return text, issueTitle, extraMarkdown, color @@ -222,7 +222,7 @@ func getReleasePayloadInfo(p *api.ReleasePayload, linkFormatter linkFormatter, w color = redColor } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } return text, color @@ -251,7 +251,7 @@ func getWikiPayloadInfo(p *api.WikiPayload, linkFormatter linkFormatter, withSen } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } return text, color, pageLink @@ -287,7 +287,7 @@ func getIssueCommentPayloadInfo(p *api.IssueCommentPayload, linkFormatter linkFo color = redColor } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } return text, issueTitle, color @@ -298,14 +298,14 @@ func getPackagePayloadInfo(p *api.PackagePayload, linkFormatter linkFormatter, w switch p.Action { case api.HookPackageCreated: - text = fmt.Sprintf("Package created: %s", refLink) + text = "Package created: " + refLink color = greenColor case api.HookPackageDeleted: - text = fmt.Sprintf("Package deleted: %s", refLink) + text = "Package deleted: " + refLink color = redColor } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } return text, color @@ -318,9 +318,9 @@ func getStatusPayloadInfo(p *api.CommitStatusPayload, linkFormatter linkFormatte color = greenColor if withSender { if user_model.IsGiteaActionsUserName(p.Sender.UserName) { - text += fmt.Sprintf(" by %s", p.Sender.FullName) + text += " by " + p.Sender.FullName } else { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } } @@ -352,7 +352,7 @@ func getWorkflowJobPayloadInfo(p *api.WorkflowJobPayload, linkFormatter linkForm color = greyColor } if withSender { - text += fmt.Sprintf(" by %s", linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName)) + text += " by " + linkFormatter(setting.AppURL+url.PathEscape(p.Sender.UserName), p.Sender.UserName) } return text, color diff --git a/services/webhook/msteams.go b/services/webhook/msteams.go index f70e235f20..07d28c3867 100644 --- a/services/webhook/msteams.go +++ b/services/webhook/msteams.go @@ -8,6 +8,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "strings" webhook_model "code.gitea.io/gitea/models/webhook" @@ -73,7 +74,7 @@ func (m msteamsConvertor) Create(p *api.CreatePayload) (MSTeamsPayload, error) { "", p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName), greenColor, - &MSTeamsFact{fmt.Sprintf("%s:", p.RefType), refName}, + &MSTeamsFact{p.RefType + ":", refName}, ), nil } @@ -90,7 +91,7 @@ func (m msteamsConvertor) Delete(p *api.DeletePayload) (MSTeamsPayload, error) { "", p.Repo.HTMLURL+"/src/"+util.PathEscapeSegments(refName), yellowColor, - &MSTeamsFact{fmt.Sprintf("%s:", p.RefType), refName}, + &MSTeamsFact{p.RefType + ":", refName}, ), nil } @@ -148,7 +149,7 @@ func (m msteamsConvertor) Push(p *api.PushPayload) (MSTeamsPayload, error) { text, titleLink, greenColor, - &MSTeamsFact{"Commit count:", fmt.Sprintf("%d", p.TotalCommits)}, + &MSTeamsFact{"Commit count:", strconv.Itoa(p.TotalCommits)}, ), nil } @@ -163,7 +164,7 @@ func (m msteamsConvertor) Issue(p *api.IssuePayload) (MSTeamsPayload, error) { extraMarkdown, p.Issue.HTMLURL, color, - &MSTeamsFact{"Issue #:", fmt.Sprintf("%d", p.Issue.ID)}, + &MSTeamsFact{"Issue #:", strconv.FormatInt(p.Issue.ID, 10)}, ), nil } @@ -178,7 +179,7 @@ func (m msteamsConvertor) IssueComment(p *api.IssueCommentPayload) (MSTeamsPaylo p.Comment.Body, p.Comment.HTMLURL, color, - &MSTeamsFact{"Issue #:", fmt.Sprintf("%d", p.Issue.ID)}, + &MSTeamsFact{"Issue #:", strconv.FormatInt(p.Issue.ID, 10)}, ), nil } @@ -193,7 +194,7 @@ func (m msteamsConvertor) PullRequest(p *api.PullRequestPayload) (MSTeamsPayload extraMarkdown, p.PullRequest.HTMLURL, color, - &MSTeamsFact{"Pull request #:", fmt.Sprintf("%d", p.PullRequest.ID)}, + &MSTeamsFact{"Pull request #:", strconv.FormatInt(p.PullRequest.ID, 10)}, ), nil } @@ -230,7 +231,7 @@ func (m msteamsConvertor) Review(p *api.PullRequestPayload, event webhook_module text, p.PullRequest.HTMLURL, color, - &MSTeamsFact{"Pull request #:", fmt.Sprintf("%d", p.PullRequest.ID)}, + &MSTeamsFact{"Pull request #:", strconv.FormatInt(p.PullRequest.ID, 10)}, ), nil } diff --git a/services/webhook/msteams_test.go b/services/webhook/msteams_test.go index d5020d3ff5..0d98b94bad 100644 --- a/services/webhook/msteams_test.go +++ b/services/webhook/msteams_test.go @@ -335,7 +335,7 @@ func TestMSTeamsPayload(t *testing.T) { assert.Equal(t, "[test/repo] New wiki page 'index' (Wiki change comment)", pl.Summary) assert.Len(t, pl.Sections, 1) assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle) - assert.Equal(t, "", pl.Sections[0].Text) + assert.Empty(t, pl.Sections[0].Text) assert.Len(t, pl.Sections[0].Facts, 2) for _, fact := range pl.Sections[0].Facts { if fact.Name == "Repository:" { @@ -356,7 +356,7 @@ func TestMSTeamsPayload(t *testing.T) { assert.Equal(t, "[test/repo] Wiki page 'index' edited (Wiki change comment)", pl.Summary) assert.Len(t, pl.Sections, 1) assert.Equal(t, "user1", pl.Sections[0].ActivitySubtitle) - assert.Equal(t, "", pl.Sections[0].Text) + assert.Empty(t, pl.Sections[0].Text) assert.Len(t, pl.Sections[0].Facts, 2) for _, fact := range pl.Sections[0].Facts { if fact.Name == "Repository:" { diff --git a/services/webhook/packagist_test.go b/services/webhook/packagist_test.go index 638dcfd302..4e77f29edc 100644 --- a/services/webhook/packagist_test.go +++ b/services/webhook/packagist_test.go @@ -210,5 +210,5 @@ func TestPackagistEmptyPayload(t *testing.T) { var body PackagistPayload err = json.NewDecoder(req.Body).Decode(&body) assert.NoError(t, err) - assert.Equal(t, "", body.PackagistRepository.URL) + assert.Empty(t, body.PackagistRepository.URL) } diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go index 288d258279..f441c2939b 100644 --- a/services/wiki/wiki_test.go +++ b/services/wiki/wiki_test.go @@ -26,7 +26,7 @@ func TestMain(m *testing.M) { func TestWebPathSegments(t *testing.T) { a := WebPathSegments("a%2Fa/b+c/d-e/f-g.-") - assert.EqualValues(t, []string{"a/a", "b c", "d e", "f-g"}, a) + assert.Equal(t, []string{"a/a", "b c", "d e", "f-g"}, a) } func TestUserTitleToWebPath(t *testing.T) { @@ -63,7 +63,7 @@ func TestWebPathToDisplayName(t *testing.T) { {"a b", "a%20b.md"}, } { _, displayName := WebPathToUserTitle(test.WebPath) - assert.EqualValues(t, test.Expected, displayName) + assert.Equal(t, test.Expected, displayName) } } @@ -80,7 +80,7 @@ func TestWebPathToGitPath(t *testing.T) { {"2000-01-02-meeting.md", "2000-01-02+meeting"}, {"2000-01-02 meeting.-.md", "2000-01-02%20meeting.-"}, } { - assert.EqualValues(t, test.Expected, WebPathToGitPath(test.WikiName)) + assert.Equal(t, test.Expected, WebPathToGitPath(test.WikiName)) } } @@ -134,9 +134,9 @@ func TestUserWebGitPathConsistency(t *testing.T) { _, userTitle1 := WebPathToUserTitle(webPath1) gitPath1 := WebPathToGitPath(webPath1) - assert.EqualValues(t, userTitle, userTitle1, "UserTitle for userTitle: %q", userTitle) - assert.EqualValues(t, webPath, webPath1, "WebPath for userTitle: %q", userTitle) - assert.EqualValues(t, gitPath, gitPath1, "GitPath for userTitle: %q", userTitle) + assert.Equal(t, userTitle, userTitle1, "UserTitle for userTitle: %q", userTitle) + assert.Equal(t, webPath, webPath1, "WebPath for userTitle: %q", userTitle) + assert.Equal(t, gitPath, gitPath1, "GitPath for userTitle: %q", userTitle) } } @@ -175,7 +175,7 @@ func TestRepository_AddWikiPage(t *testing.T) { gitPath := WebPathToGitPath(webPath) entry, err := masterTree.GetTreeEntryByPath(gitPath) assert.NoError(t, err) - assert.EqualValues(t, gitPath, entry.Name(), "%s not added correctly", userTitle) + assert.Equal(t, gitPath, entry.Name(), "%s not added correctly", userTitle) }) } @@ -220,7 +220,7 @@ func TestRepository_EditWikiPage(t *testing.T) { gitPath := WebPathToGitPath(webPath) entry, err := masterTree.GetTreeEntryByPath(gitPath) assert.NoError(t, err) - assert.EqualValues(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName) + assert.Equal(t, gitPath, entry.Name(), "%s not edited correctly", newWikiName) if newWikiName != "Home" { _, err := masterTree.GetTreeEntryByPath("Home.md") @@ -290,7 +290,7 @@ func TestPrepareWikiFileName(t *testing.T) { t.Errorf("expect to find an escaped file but we could not detect one") } } - assert.EqualValues(t, tt.wikiPath, newWikiPath) + assert.Equal(t, tt.wikiPath, newWikiPath) }) } } @@ -312,13 +312,13 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) { existence, newWikiPath, err := prepareGitPath(gitRepo, "master", "Home") assert.False(t, existence) assert.NoError(t, err) - assert.EqualValues(t, "Home.md", newWikiPath) + assert.Equal(t, "Home.md", newWikiPath) } func TestWebPathConversion(t *testing.T) { assert.Equal(t, "path/wiki", WebPathToURLPath(WebPath("path/wiki"))) assert.Equal(t, "wiki", WebPathToURLPath(WebPath("wiki"))) - assert.Equal(t, "", WebPathToURLPath(WebPath(""))) + assert.Empty(t, WebPathToURLPath(WebPath(""))) } func TestWebPathFromRequest(t *testing.T) { diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl index 29a5e1b473..88dadeb3ee 100644 --- a/templates/admin/config.tmpl +++ b/templates/admin/config.tmpl @@ -148,7 +148,7 @@ {{ctx.Locale.Tr "admin.config.enable_openid_signin"}} {{svg (Iif .Service.EnableOpenIDSignIn "octicon-check" "octicon-x")}} {{ctx.Locale.Tr "admin.config.require_sign_in_view"}} - {{svg (Iif .Service.RequireSignInView "octicon-check" "octicon-x")}} + {{svg (Iif .Service.RequireSignInViewStrict "octicon-check" "octicon-x")}} {{ctx.Locale.Tr "admin.config.mail_notify"}} {{svg (Iif .Service.EnableNotifyMail "octicon-check" "octicon-x")}} {{ctx.Locale.Tr "admin.config.enable_captcha"}} diff --git a/templates/devtest/badge-actions-svg.tmpl b/templates/devtest/badge-actions-svg.tmpl index 8125793bb3..5be4fb3131 100644 --- a/templates/devtest/badge-actions-svg.tmpl +++ b/templates/devtest/badge-actions-svg.tmpl @@ -3,9 +3,16 @@ Actions SVG - {{range $fontName := .BadgeFontFamilyNames}} - {{$fontName}} - {{end}} + + {{range $fontName := .BadgeFontFamilyNames}} + {{$fontName}} + {{end}} + + + {{range $style := .BadgeStyles}} + {{$style}} + {{end}} + submit diff --git a/templates/devtest/fomantic-dropdown.tmpl b/templates/devtest/fomantic-dropdown.tmpl index d41a161e86..a10dc890ce 100644 --- a/templates/devtest/fomantic-dropdown.tmpl +++ b/templates/devtest/fomantic-dropdown.tmpl @@ -75,12 +75,12 @@ Selection {{/* the "selection" class is optional, it will be added by JS automatically */}} - + a abcdefuvwxyz loooooooooooooooooooooooooooooooooooooooooooooooooooooooooong - + loooooooooooooooooooooooooooooooooooooooooooooooooooooooooong abcdefuvwxyz a diff --git a/templates/projects/view.tmpl b/templates/projects/view.tmpl index 79925e69cc..d6a335ef4b 100644 --- a/templates/projects/view.tmpl +++ b/templates/projects/view.tmpl @@ -13,7 +13,7 @@ "UserSearchList" $.Assignees "SelectedUserId" $.AssigneeID "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") - "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assignee_no_assignee") "TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee") }} diff --git a/templates/repo/actions/workflow_dispatch.tmpl b/templates/repo/actions/workflow_dispatch.tmpl index 55fe122419..540bbe9162 100644 --- a/templates/repo/actions/workflow_dispatch.tmpl +++ b/templates/repo/actions/workflow_dispatch.tmpl @@ -10,7 +10,7 @@ {{ctx.Locale.Tr "actions.workflow.from_ref"}}: - + {{svg "octicon-git-branch" 14}} {{index .Branches 0}} diff --git a/templates/repo/branch/list.tmpl b/templates/repo/branch/list.tmpl index c0accf16fa..19797229bf 100644 --- a/templates/repo/branch/list.tmpl +++ b/templates/repo/branch/list.tmpl @@ -27,7 +27,7 @@ {{svg "octicon-copy" 14}} {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DefaultBranchBranch.DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DefaultBranchBranch.DBBranch.CommitID)}} - {{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DefaultBranchBranch.DBBranch.CommitTime}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}} + {{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeCommentMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DefaultBranchBranch.DBBranch.CommitTime}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}} {{/* FIXME: here and below, the tw-overflow-visible is not quite right but it is still needed the moment: to show the important buttons when the width is narrow */}} @@ -103,7 +103,7 @@ {{svg "octicon-copy" 14}} {{template "repo/commit_statuses" dict "Status" (index $.CommitStatus .DBBranch.CommitID) "Statuses" (index $.CommitStatuses .DBBranch.CommitID)}} - {{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DBBranch.CommitTime}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}} + {{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DBBranch.CommitMessage ($.Repository.ComposeCommentMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DBBranch.CommitTime}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}} {{end}} diff --git a/templates/repo/branch_dropdown.tmpl b/templates/repo/branch_dropdown.tmpl index f679b8744b..261d0ea409 100644 --- a/templates/repo/branch_dropdown.tmpl +++ b/templates/repo/branch_dropdown.tmpl @@ -46,7 +46,7 @@ Search "repo/branch_dropdown" in the template directory to find all occurrences. data-enable-feed="{{ctx.RootData.EnableFeed}}" > {{/* show dummy elements before Vue componment is mounted, this code must match the code in BranchTagSelector.vue */}} - + {{if not .DropdownFixedText}} diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl index ff3dccd534..5639c87a82 100644 --- a/templates/repo/commit_page.tmpl +++ b/templates/repo/commit_page.tmpl @@ -5,7 +5,7 @@ - {{ctx.RenderUtils.RenderCommitMessage .Commit.Message ($.Repository.ComposeMetas ctx)}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}} + {{ctx.RenderUtils.RenderCommitMessage .Commit.Message ($.Repository.ComposeCommentMetas ctx)}}{{template "repo/commit_statuses" dict "Status" .CommitStatus "Statuses" .CommitStatuses}} {{if not $.PageIsWiki}} @@ -122,7 +122,7 @@ {{end}} {{if IsMultilineCommitMessage .Commit.Message}} - {{ctx.RenderUtils.RenderCommitBody .Commit.Message ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitBody .Commit.Message ($.Repository.ComposeCommentMetas ctx)}} {{end}} {{template "repo/commit_load_branches_and_tags" .}} diff --git a/templates/repo/commit_statuses.tmpl b/templates/repo/commit_statuses.tmpl index a6f75584a3..1bbfb33105 100644 --- a/templates/repo/commit_statuses.tmpl +++ b/templates/repo/commit_statuses.tmpl @@ -1,10 +1,10 @@ {{if .Statuses}} {{if and (eq (len .Statuses) 1) .Status.TargetURL}} - + {{template "repo/commit_status" .Status}} {{else}} - + {{template "repo/commit_status" .Status}} {{end}} diff --git a/templates/repo/commits_list.tmpl b/templates/repo/commits_list.tmpl index e1bd6b73ae..50e6708dcf 100644 --- a/templates/repo/commits_list.tmpl +++ b/templates/repo/commits_list.tmpl @@ -44,7 +44,7 @@ {{.Summary | ctx.RenderUtils.RenderEmoji}} {{else}} {{$commitLink:= printf "%s/commit/%s" $commitRepoLink (PathEscape .ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink ($.Repository.ComposeCommentMetas ctx)}} {{end}} {{if IsMultilineCommitMessage .Message}} @@ -52,7 +52,7 @@ {{end}} {{template "repo/commit_statuses" dict "Status" .Status "Statuses" .Statuses}} {{if IsMultilineCommitMessage .Message}} - {{ctx.RenderUtils.RenderCommitBody .Message ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitBody .Message ($.Repository.ComposeCommentMetas ctx)}} {{end}} {{if $.CommitsTagsMap}} {{range (index $.CommitsTagsMap .ID.String)}} diff --git a/templates/repo/commits_list_small.tmpl b/templates/repo/commits_list_small.tmpl index 2acf7c58b8..b054ce19a5 100644 --- a/templates/repo/commits_list_small.tmpl +++ b/templates/repo/commits_list_small.tmpl @@ -15,7 +15,7 @@ {{$commitLink:= printf "%s/%s" $commitBaseLink (PathEscape .ID.String)}} - {{- ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx) -}} + {{- ctx.RenderUtils.RenderCommitMessageLinkSubject .Message $commitLink ($.comment.Issue.PullRequest.BaseRepo.ComposeCommentMetas ctx) -}} {{if IsMultilineCommitMessage .Message}} @@ -29,7 +29,7 @@ {{if IsMultilineCommitMessage .Message}} - {{- ctx.RenderUtils.RenderCommitBody .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx) -}} + {{- ctx.RenderUtils.RenderCommitBody .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeCommentMetas ctx) -}} {{end}} {{end}} diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl index a90c26b423..ada7e0c092 100644 --- a/templates/repo/create.tmpl +++ b/templates/repo/create.tmpl @@ -12,23 +12,23 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{svg "octicon-triangle-down" 14 "dropdown icon"}} - {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl index 05cfffd2b7..0c9e3f0698 100644 --- a/templates/repo/diff/compare.tmpl +++ b/templates/repo/diff/compare.tmpl @@ -189,7 +189,7 @@ {{template "shared/issueicon" .}} - {{ctx.RenderUtils.RenderIssueTitle .PullRequest.Issue.Title ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderIssueTitle .PullRequest.Issue.Title ($.Repository.ComposeCommentMetas ctx)}} #{{.PullRequest.Issue.Index}} diff --git a/templates/repo/graph/commits.tmpl b/templates/repo/graph/commits.tmpl index 6af0ba1f0f..55a91ac195 100644 --- a/templates/repo/graph/commits.tmpl +++ b/templates/repo/graph/commits.tmpl @@ -8,7 +8,7 @@ {{template "repo/commit_sign_badge" dict "Commit" $commit.Commit "CommitBaseLink" (print $.RepoLink "/commit") "CommitSignVerification" $commit.Verification}} - {{ctx.RenderUtils.RenderCommitMessage $commit.Subject ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitMessage $commit.Subject ($.Repository.ComposeCommentMetas ctx)}} diff --git a/templates/repo/issue/branch_selector_field.tmpl b/templates/repo/issue/branch_selector_field.tmpl index 9183b7b46a..c8b67490ac 100644 --- a/templates/repo/issue/branch_selector_field.tmpl +++ b/templates/repo/issue/branch_selector_field.tmpl @@ -14,7 +14,7 @@ Still needs to figure out: */}} {{if and (not .Issue.IsPull) (not .PageIsComparePull)}} - diff --git a/templates/repo/issue/filter_list.tmpl b/templates/repo/issue/filter_list.tmpl index 58ca4a7c00..cd04f1c317 100644 --- a/templates/repo/issue/filter_list.tmpl +++ b/templates/repo/issue/filter_list.tmpl @@ -94,7 +94,7 @@ "UserSearchList" $.Assignees "SelectedUserId" $.AssigneeID "TextFilterTitle" (ctx.Locale.Tr "repo.issues.filter_assignee") - "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assginee_no_assignee") + "TextFilterMatchNone" (ctx.Locale.Tr "repo.issues.filter_assignee_no_assignee") "TextFilterMatchAny" (ctx.Locale.Tr "repo.issues.filter_assignee_any_assignee") }} diff --git a/templates/repo/issue/view_content/reference_issue_dialog.tmpl b/templates/repo/issue/view_content/reference_issue_dialog.tmpl index f6ffeef26d..c5b860d48e 100644 --- a/templates/repo/issue/view_content/reference_issue_dialog.tmpl +++ b/templates/repo/issue/view_content/reference_issue_dialog.tmpl @@ -7,7 +7,7 @@ {{.CsrfTokenHtml}} {{ctx.Locale.Tr "repository"}} - + {{.Repository.FullName}} diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl index dcc1f48c2c..a4be598540 100644 --- a/templates/repo/issue/view_title.tmpl +++ b/templates/repo/issue/view_title.tmpl @@ -13,7 +13,7 @@ {{$canEditIssueTitle := and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .Repository.IsArchived)}} - {{ctx.RenderUtils.RenderIssueTitle .Issue.Title ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderIssueTitle .Issue.Title ($.Repository.ComposeCommentMetas ctx)}} #{{.Issue.Index}} diff --git a/templates/repo/latest_commit.tmpl b/templates/repo/latest_commit.tmpl index 0341d60eb2..da457e423a 100644 --- a/templates/repo/latest_commit.tmpl +++ b/templates/repo/latest_commit.tmpl @@ -21,10 +21,10 @@ {{template "repo/commit_statuses" dict "Status" .LatestCommitStatus "Statuses" .LatestCommitStatuses}} {{$commitLink:= printf "%s/commit/%s" .RepoLink (PathEscape .LatestCommit.ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject .LatestCommit.Message $commitLink ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitMessageLinkSubject .LatestCommit.Message $commitLink ($.Repository.ComposeCommentMetas ctx)}} {{if IsMultilineCommitMessage .LatestCommit.Message}} ... - {{ctx.RenderUtils.RenderCommitBody .LatestCommit.Message ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitBody .LatestCommit.Message ($.Repository.ComposeCommentMetas ctx)}} {{end}} {{end}} diff --git a/templates/repo/migrate/codebase.tmpl b/templates/repo/migrate/codebase.tmpl index d4ca269f02..f4de8ff236 100644 --- a/templates/repo/migrate/codebase.tmpl +++ b/templates/repo/migrate/codebase.tmpl @@ -60,22 +60,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/codecommit.tmpl b/templates/repo/migrate/codecommit.tmpl index 53ca7dda3d..275a2aef09 100644 --- a/templates/repo/migrate/codecommit.tmpl +++ b/templates/repo/migrate/codecommit.tmpl @@ -61,22 +61,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/git.tmpl b/templates/repo/migrate/git.tmpl index 3f447f76eb..41139d4fd6 100644 --- a/templates/repo/migrate/git.tmpl +++ b/templates/repo/migrate/git.tmpl @@ -34,22 +34,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar .}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/gitbucket.tmpl b/templates/repo/migrate/gitbucket.tmpl index 559988951b..c89aa6c744 100644 --- a/templates/repo/migrate/gitbucket.tmpl +++ b/templates/repo/migrate/gitbucket.tmpl @@ -76,22 +76,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/gitea.tmpl b/templates/repo/migrate/gitea.tmpl index 3d692129d5..55cf61a77f 100644 --- a/templates/repo/migrate/gitea.tmpl +++ b/templates/repo/migrate/gitea.tmpl @@ -72,22 +72,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar .}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/github.tmpl b/templates/repo/migrate/github.tmpl index 850a2b3c71..86b585b861 100644 --- a/templates/repo/migrate/github.tmpl +++ b/templates/repo/migrate/github.tmpl @@ -74,22 +74,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/gitlab.tmpl b/templates/repo/migrate/gitlab.tmpl index 9bafa122f1..edd69f0027 100644 --- a/templates/repo/migrate/gitlab.tmpl +++ b/templates/repo/migrate/gitlab.tmpl @@ -71,22 +71,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/gogs.tmpl b/templates/repo/migrate/gogs.tmpl index 0495ce67fb..9149c43239 100644 --- a/templates/repo/migrate/gogs.tmpl +++ b/templates/repo/migrate/gogs.tmpl @@ -74,22 +74,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar .}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/migrate/onedev.tmpl b/templates/repo/migrate/onedev.tmpl index 55945154ef..a25ccf9438 100644 --- a/templates/repo/migrate/onedev.tmpl +++ b/templates/repo/migrate/onedev.tmpl @@ -61,22 +61,22 @@ {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl index 879e5328f2..9a6c44077f 100644 --- a/templates/repo/pulls/fork.tmpl +++ b/templates/repo/pulls/fork.tmpl @@ -10,24 +10,24 @@ {{.CsrfTokenHtml}} {{ctx.Locale.Tr "repo.owner"}} - + - + {{ctx.AvatarUtils.Avatar .ContextUser 28 "mini"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} {{if .CanForkToUser}} - + {{ctx.AvatarUtils.Avatar .SignedUser 28 "mini"}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{end}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar . 28 "mini"}} - {{.ShortName 40}} + {{.ShortName 40}} {{end}} @@ -52,10 +52,10 @@ {{ctx.Locale.Tr "repo.fork_branch"}} - + - {{ctx.Locale.Tr "repo.all_branches"}} + {{ctx.Locale.Tr "repo.all_branches"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}} diff --git a/templates/repo/settings/githooks.tmpl b/templates/repo/settings/githooks.tmpl index 1a603f9fe8..9b17af1406 100644 --- a/templates/repo/settings/githooks.tmpl +++ b/templates/repo/settings/githooks.tmpl @@ -4,18 +4,14 @@ {{ctx.Locale.Tr "repo.settings.githooks"}} - - - {{ctx.Locale.Tr "repo.settings.githooks_desc"}} - + + {{ctx.Locale.Tr "repo.settings.githooks_desc"}} {{range .Hooks}} - - {{svg "octicon-dot-fill" 22}} - {{.Name}} - - {{svg "octicon-pencil"}} - - + + {{svg "octicon-dot-fill" 22}} + {{.Name}} + {{svg "octicon-pencil"}} + {{end}} diff --git a/templates/repo/settings/webhook/base_list.tmpl b/templates/repo/settings/webhook/base_list.tmpl index 36e75a7eb5..a63771b97e 100644 --- a/templates/repo/settings/webhook/base_list.tmpl +++ b/templates/repo/settings/webhook/base_list.tmpl @@ -8,14 +8,12 @@ - - - {{.Description}} - + + {{.Description}} {{range .Webhooks}} - - {{svg "octicon-dot-fill" 22}} - + + {{svg "octicon-dot-fill" 22}} + {{.URL}} {{svg "octicon-pencil"}} diff --git a/templates/repo/view_list.tmpl b/templates/repo/view_list.tmpl index 4745110dd2..572987a986 100644 --- a/templates/repo/view_list.tmpl +++ b/templates/repo/view_list.tmpl @@ -9,13 +9,14 @@ {{svg "octicon-file-directory-fill"}} .. {{end}} + {{$.FileIconPoolHTML}} {{range $item := .Files}} {{$entry := $item.Entry}} {{$commit := $item.Commit}} {{$submoduleFile := $item.SubmoduleFile}} - {{ctx.RenderUtils.RenderFileIcon $entry}} + {{index $.FileIcons $entry.Name}} {{if $entry.IsSubModule}} {{$submoduleLink := $submoduleFile.SubmoduleWebLink ctx}} {{if $submoduleLink}} @@ -46,7 +47,7 @@ {{if $commit}} {{$commitLink := printf "%s/commit/%s" $.RepoLink (PathEscape $commit.ID.String)}} - {{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.Message $commitLink ($.Repository.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitMessageLinkSubject $commit.Message $commitLink ($.Repository.ComposeCommentMetas ctx)}} {{else}} … {{/* will be loaded again by LastCommitLoaderURL */}} {{end}} diff --git a/templates/shared/actions/runner_badge_flat-square.tmpl b/templates/shared/actions/runner_badge_flat-square.tmpl new file mode 100644 index 0000000000..cc1dc1e8f3 --- /dev/null +++ b/templates/shared/actions/runner_badge_flat-square.tmpl @@ -0,0 +1,15 @@ + + {{.Badge.Label.Text}}: {{.Badge.Message.Text}} + + + + + + {{.Badge.Label.Text}} + {{.Badge.Message.Text}} + + diff --git a/templates/shared/actions/runner_badge.tmpl b/templates/shared/actions/runner_badge_flat.tmpl similarity index 100% rename from templates/shared/actions/runner_badge.tmpl rename to templates/shared/actions/runner_badge_flat.tmpl diff --git a/templates/status/500.tmpl b/templates/status/500.tmpl index 198f1ea898..6dfa2d8a8c 100644 --- a/templates/status/500.tmpl +++ b/templates/status/500.tmpl @@ -38,7 +38,7 @@ {{if .ErrorMsg}} {{ctx.Locale.Tr "error.occurred"}}: - {{.ErrorMsg}} + {{.ErrorMsg}} {{end}} diff --git a/templates/swagger/v1_json.tmpl b/templates/swagger/v1_json.tmpl index de7c8dc6f0..d0e41e8094 100644 --- a/templates/swagger/v1_json.tmpl +++ b/templates/swagger/v1_json.tmpl @@ -20411,10 +20411,20 @@ "type": "string", "x-go-name": "HTMLURL" }, + "last_author_date": { + "type": "string", + "format": "date-time", + "x-go-name": "LastAuthorDate" + }, "last_commit_sha": { "type": "string", "x-go-name": "LastCommitSHA" }, + "last_committer_date": { + "type": "string", + "format": "date-time", + "x-go-name": "LastCommitterDate" + }, "name": { "type": "string", "x-go-name": "Name" diff --git a/templates/user/dashboard/feeds.tmpl b/templates/user/dashboard/feeds.tmpl index 47686dd442..366bb80b42 100644 --- a/templates/user/dashboard/feeds.tmpl +++ b/templates/user/dashboard/feeds.tmpl @@ -94,7 +94,7 @@ {{ShortSha .Sha1}} - {{ctx.RenderUtils.RenderCommitMessage .Message ($repo.ComposeMetas ctx)}} + {{ctx.RenderUtils.RenderCommitMessage .Message ($repo.ComposeCommentMetas ctx)}} {{end}} diff --git a/templates/user/dashboard/navbar.tmpl b/templates/user/dashboard/navbar.tmpl index a828bc90e4..2774ec5da2 100644 --- a/templates/user/dashboard/navbar.tmpl +++ b/templates/user/dashboard/navbar.tmpl @@ -2,32 +2,32 @@ - + {{ctx.AvatarUtils.Avatar .ContextUser 24 "tw-mr-1"}} - {{.ContextUser.ShortName 40}} + {{.ContextUser.ShortName 40}} {{if .ContextUser.Visibility.IsLimited}}{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}{{end}} {{if .ContextUser.Visibility.IsPrivate}}{{ctx.Locale.Tr "org.settings.visibility.private_shortname"}}{{end}} {{svg "octicon-triangle-down" 14 "dropdown icon tw-ml-1"}} - + {{ctx.Locale.Tr "home.switch_dashboard_context"}} - - + + {{ctx.AvatarUtils.Avatar .SignedUser}} - {{.SignedUser.ShortName 40}} + {{.SignedUser.ShortName 40}} {{if .SignedUser.Visibility.IsLimited}}{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}{{end}} {{if .SignedUser.Visibility.IsPrivate}}{{ctx.Locale.Tr "org.settings.visibility.private_shortname"}}{{end}} {{range .Orgs}} - + {{ctx.AvatarUtils.Avatar .}} - {{.ShortName 40}} + {{.ShortName 40}} {{if .Visibility.IsLimited}}{{ctx.Locale.Tr "org.settings.visibility.limited_shortname"}}{{end}} {{if .Visibility.IsPrivate}}{{ctx.Locale.Tr "org.settings.visibility.private_shortname"}}{{end}} diff --git a/tests/e2e/e2e_test.go b/tests/e2e/e2e_test.go index ece136be50..af631ca8fd 100644 --- a/tests/e2e/e2e_test.go +++ b/tests/e2e/e2e_test.go @@ -94,7 +94,7 @@ func TestE2e(t *testing.T) { onGiteaRun(t, func(*testing.T, *url.URL) { cmd := exec.Command(runArgs[0], runArgs...) cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, fmt.Sprintf("GITEA_URL=%s", setting.AppURL)) + cmd.Env = append(cmd.Env, "GITEA_URL="+setting.AppURL) var stdout, stderr bytes.Buffer cmd.Stdout = &stdout diff --git a/tests/integration/actions_job_test.go b/tests/integration/actions_job_test.go index 89c93e7a75..4f4456a4e5 100644 --- a/tests/integration/actions_job_test.go +++ b/tests/integration/actions_job_test.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "reflect" + "strconv" "testing" "time" @@ -137,9 +138,9 @@ jobs: runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { - t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { + t.Run("test "+tc.treePath, func(t *testing.T) { // create the workflow file - opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, fmt.Sprintf("create %s", tc.treePath), tc.fileContent) + opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, "create "+tc.treePath, tc.fileContent) fileResp := createWorkflowFile(t, token, user2.Name, apiRepo.Name, tc.treePath, opts) // fetch and execute task @@ -320,8 +321,8 @@ jobs: runner.registerAsRepoRunner(t, user2.Name, apiRepo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { - t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { - opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, fmt.Sprintf("create %s", tc.treePath), tc.fileContent) + t.Run("test "+tc.treePath, func(t *testing.T) { + opts := getWorkflowCreateFileOptions(user2, apiRepo.DefaultBranch, "create "+tc.treePath, tc.fileContent) createWorkflowFile(t, token, user2.Name, apiRepo.Name, tc.treePath, opts) for i := 0; i < len(tc.outcomes); i++ { @@ -371,7 +372,7 @@ jobs: steps: - run: echo 'test the pull' ` - opts := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, fmt.Sprintf("create %s", wfTreePath), wfFileContent) + opts := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create "+wfTreePath, wfFileContent) createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wfTreePath, opts) // user2 creates a pull request doAPICreateFile(user2APICtx, "user2-patch.txt", &api.CreateFileOptions{ @@ -418,9 +419,9 @@ jobs: assert.Equal(t, actionRun.Repo.OwnerName+"/"+actionRun.Repo.Name, gtCtx["repository"].GetStringValue()) assert.Equal(t, actionRun.Repo.OwnerName, gtCtx["repository_owner"].GetStringValue()) assert.Equal(t, actionRun.Repo.HTMLURL(), gtCtx["repositoryUrl"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRunJob.RunID), gtCtx["run_id"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRun.Index), gtCtx["run_number"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRunJob.Attempt), gtCtx["run_attempt"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRunJob.RunID, 10), gtCtx["run_id"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRun.Index, 10), gtCtx["run_number"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRunJob.Attempt, 10), gtCtx["run_attempt"].GetStringValue()) assert.Equal(t, "Actions", gtCtx["secret_source"].GetStringValue()) assert.Equal(t, setting.AppURL, gtCtx["server_url"].GetStringValue()) assert.Equal(t, actionRun.CommitSHA, gtCtx["sha"].GetStringValue()) @@ -463,7 +464,7 @@ jobs: steps: - run: echo 'test the pull' ` - opts := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, fmt.Sprintf("create %s", wfTreePath), wfFileContent) + opts := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create "+wfTreePath, wfFileContent) createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wfTreePath, opts) // user2 creates a pull request doAPICreateFile(user2APICtx, "user2-patch.txt", &api.CreateFileOptions{ @@ -510,9 +511,9 @@ jobs: assert.Equal(t, actionRun.Repo.OwnerName+"/"+actionRun.Repo.Name, gtCtx["repository"].GetStringValue()) assert.Equal(t, actionRun.Repo.OwnerName, gtCtx["repository_owner"].GetStringValue()) assert.Equal(t, actionRun.Repo.HTMLURL(), gtCtx["repositoryUrl"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRunJob.RunID), gtCtx["run_id"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRun.Index), gtCtx["run_number"].GetStringValue()) - assert.Equal(t, fmt.Sprint(actionRunJob.Attempt), gtCtx["run_attempt"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRunJob.RunID, 10), gtCtx["run_id"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRun.Index, 10), gtCtx["run_number"].GetStringValue()) + assert.Equal(t, strconv.FormatInt(actionRunJob.Attempt, 10), gtCtx["run_attempt"].GetStringValue()) assert.Equal(t, "Actions", gtCtx["secret_source"].GetStringValue()) assert.Equal(t, setting.AppURL, gtCtx["server_url"].GetStringValue()) assert.Equal(t, actionRun.CommitSHA, gtCtx["sha"].GetStringValue()) diff --git a/tests/integration/actions_log_test.go b/tests/integration/actions_log_test.go index cd20604b84..503bda97c9 100644 --- a/tests/integration/actions_log_test.go +++ b/tests/integration/actions_log_test.go @@ -156,7 +156,7 @@ jobs: runner.registerAsRepoRunner(t, user2.Name, repo.Name, "mock-runner", []string{"ubuntu-latest"}, false) for _, tc := range testCases { - t.Run(fmt.Sprintf("test %s", tc.treePath), func(t *testing.T) { + t.Run("test "+tc.treePath, func(t *testing.T) { var resetFunc func() if tc.zstdEnabled { resetFunc = test.MockVariableValue(&setting.Actions.LogCompression, "zstd") @@ -167,7 +167,7 @@ jobs: } // create the workflow file - opts := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, fmt.Sprintf("create %s", tc.treePath), tc.fileContent) + opts := getWorkflowCreateFileOptions(user2, repo.DefaultBranch, "create "+tc.treePath, tc.fileContent) createWorkflowFile(t, token, user2.Name, repo.Name, tc.treePath, opts) // fetch and execute tasks diff --git a/tests/integration/actions_runner_test.go b/tests/integration/actions_runner_test.go index ee92032e9f..75402929a1 100644 --- a/tests/integration/actions_runner_test.go +++ b/tests/integration/actions_runner_test.go @@ -37,7 +37,7 @@ func newMockRunner() *mockRunner { } func newMockRunnerClient(uuid, token string) *mockRunnerClient { - baseURL := fmt.Sprintf("%sapi/actions", setting.AppURL) + baseURL := setting.AppURL + "api/actions" opt := connect.WithInterceptors(connect.UnaryInterceptorFunc(func(next connect.UnaryFunc) connect.UnaryFunc { return func(ctx context.Context, req connect.AnyRequest) (connect.AnyResponse, error) { diff --git a/tests/integration/actions_trigger_test.go b/tests/integration/actions_trigger_test.go index 096f51dfc0..f576dc38ab 100644 --- a/tests/integration/actions_trigger_test.go +++ b/tests/integration/actions_trigger_test.go @@ -4,6 +4,7 @@ package integration import ( + "encoding/base64" "fmt" "net/http" "net/url" @@ -28,6 +29,7 @@ import ( api "code.gitea.io/gitea/modules/structs" "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/timeutil" + "code.gitea.io/gitea/modules/util" issue_service "code.gitea.io/gitea/services/issue" pull_service "code.gitea.io/gitea/services/pull" release_service "code.gitea.io/gitea/services/release" @@ -286,7 +288,7 @@ jobs: ContentReader: strings.NewReader("bar"), }, }, - Message: fmt.Sprintf("%s add bar", setting.Actions.SkipWorkflowStrings[0]), + Message: setting.Actions.SkipWorkflowStrings[0] + " add bar", OldBranch: "master", NewBranch: "master", Author: &files_service.IdentityOptions{ @@ -1368,3 +1370,81 @@ jobs: assert.Equal(t, "true", dispatchPayload.Inputs["myinput3"]) }) } + +func TestClosePullRequestWithPath(t *testing.T) { + onGiteaRun(t, func(t *testing.T, u *url.URL) { + // user2 is the owner of the base repo + user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) + user2Token := getTokenForLoggedInUser(t, loginUser(t, user2.Name), auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) + // user4 is the owner of the fork repo + user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + user4Token := getTokenForLoggedInUser(t, loginUser(t, user4.Name), auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) + + // create the base repo + apiBaseRepo := createActionsTestRepo(t, user2Token, "close-pull-request-with-path", false) + baseRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiBaseRepo.ID}) + user2APICtx := NewAPITestContext(t, baseRepo.OwnerName, baseRepo.Name, auth_model.AccessTokenScopeWriteRepository) + + // init the workflow + wfTreePath := ".gitea/workflows/pull.yml" + wfFileContent := `name: Pull Request +on: + pull_request: + types: + - closed + paths: + - 'app/**' +jobs: + echo: + runs-on: ubuntu-latest + steps: + - run: echo 'Hello World' +` + opts1 := getWorkflowCreateFileOptions(user2, baseRepo.DefaultBranch, "create "+wfTreePath, wfFileContent) + createWorkflowFile(t, user2Token, baseRepo.OwnerName, baseRepo.Name, wfTreePath, opts1) + + // user4 forks the repo + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/forks", baseRepo.OwnerName, baseRepo.Name), + &api.CreateForkOption{ + Name: util.ToPointer("close-pull-request-with-path-fork"), + }).AddTokenAuth(user4Token) + resp := MakeRequest(t, req, http.StatusAccepted) + var apiForkRepo api.Repository + DecodeJSON(t, resp, &apiForkRepo) + forkRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: apiForkRepo.ID}) + user4APICtx := NewAPITestContext(t, user4.Name, forkRepo.Name, auth_model.AccessTokenScopeWriteRepository) + + // user4 creates a pull request to add file "app/main.go" + doAPICreateFile(user4APICtx, "app/main.go", &api.CreateFileOptions{ + FileOptions: api.FileOptions{ + NewBranchName: "user4/add-main", + Message: "create main.go", + Author: api.Identity{ + Name: user4.Name, + Email: user4.Email, + }, + Committer: api.Identity{ + Name: user4.Name, + Email: user4.Email, + }, + Dates: api.CommitDateOptions{ + Author: time.Now(), + Committer: time.Now(), + }, + }, + ContentBase64: base64.StdEncoding.EncodeToString([]byte("// main.go")), + })(t) + apiPull, err := doAPICreatePullRequest(user4APICtx, baseRepo.OwnerName, baseRepo.Name, baseRepo.DefaultBranch, user4.Name+":user4/add-main")(t) + assert.NoError(t, err) + + doAPIMergePullRequest(user2APICtx, baseRepo.OwnerName, baseRepo.Name, apiPull.Index)(t) + + pullRequest := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: apiPull.ID}) + + // load and compare ActionRun + assert.Equal(t, 1, unittest.GetCount(t, &actions_model.ActionRun{RepoID: baseRepo.ID})) + actionRun := unittest.AssertExistsAndLoadBean(t, &actions_model.ActionRun{RepoID: baseRepo.ID}) + assert.Equal(t, actions_module.GithubEventPullRequest, actionRun.TriggerEvent) + assert.Equal(t, pullRequest.MergedCommitID, actionRun.CommitSHA) + }) +} diff --git a/tests/integration/api_activitypub_person_test.go b/tests/integration/api_activitypub_person_test.go index 17d628a483..9bb1f2736e 100644 --- a/tests/integration/api_activitypub_person_test.go +++ b/tests/integration/api_activitypub_person_test.go @@ -72,10 +72,10 @@ func TestActivityPubPerson(t *testing.T) { ctx := t.Context() user1, err := user_model.GetUserByName(ctx, username1) assert.NoError(t, err) - user1url := fmt.Sprintf("%s/api/v1/activitypub/user-id/1#main-key", srv.URL) + user1url := srv.URL + "/api/v1/activitypub/user-id/1#main-key" c, err := activitypub.NewClient(db.DefaultContext, user1, user1url) assert.NoError(t, err) - user2inboxurl := fmt.Sprintf("%s/api/v1/activitypub/user-id/2/inbox", srv.URL) + user2inboxurl := srv.URL + "/api/v1/activitypub/user-id/2/inbox" // Signed request succeeds resp, err := c.Post([]byte{}, user2inboxurl) diff --git a/tests/integration/api_admin_test.go b/tests/integration/api_admin_test.go index b42f05fc55..d28a103e59 100644 --- a/tests/integration/api_admin_test.go +++ b/tests/integration/api_admin_test.go @@ -88,7 +88,7 @@ func TestAPISudoUser(t *testing.T) { normalUsername := "user2" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeReadUser) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user?sudo=%s", normalUsername)). + req := NewRequest(t, "GET", "/api/v1/user?sudo="+normalUsername). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var user api.User @@ -103,7 +103,7 @@ func TestAPISudoUserForbidden(t *testing.T) { normalUsername := "user2" token := getUserToken(t, normalUsername, auth_model.AccessTokenScopeReadAdmin) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user?sudo=%s", adminUsername)). + req := NewRequest(t, "GET", "/api/v1/user?sudo="+adminUsername). AddTokenAuth(token) MakeRequest(t, req, http.StatusForbidden) } @@ -193,7 +193,7 @@ func TestAPIEditUser(t *testing.T) { defer tests.PrepareTestEnv(t)() adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s", "user2") + urlStr := "/api/v1/admin/users/" + "user2" fullNameToChange := "Full Name User 2" req := NewRequestWithValues(t, "PATCH", urlStr, map[string]string{ @@ -217,7 +217,7 @@ func TestAPIEditUser(t *testing.T) { errMap := make(map[string]any) json.Unmarshal(resp.Body.Bytes(), &errMap) - assert.EqualValues(t, "e-mail invalid [email: ]", errMap["message"].(string)) + assert.Equal(t, "e-mail invalid [email: ]", errMap["message"].(string)) user2 = unittest.AssertExistsAndLoadBean(t, &user_model.User{LoginName: "user2"}) assert.False(t, user2.IsRestricted) @@ -374,7 +374,7 @@ func TestAPIEditUser_NotAllowedEmailDomain(t *testing.T) { adminUsername := "user1" token := getUserToken(t, adminUsername, auth_model.AccessTokenScopeWriteAdmin) - urlStr := fmt.Sprintf("/api/v1/admin/users/%s", "user2") + urlStr := "/api/v1/admin/users/" + "user2" newEmail := "user2@example1.com" req := NewRequestWithJSON(t, "PATCH", urlStr, api.EditUserOption{ diff --git a/tests/integration/api_branch_test.go b/tests/integration/api_branch_test.go index d64dd97f93..16e1f2812e 100644 --- a/tests/integration/api_branch_test.go +++ b/tests/integration/api_branch_test.go @@ -24,13 +24,13 @@ func testAPIGetBranch(t *testing.T, branchName string, exists bool) { AddTokenAuth(token) resp := MakeRequest(t, req, NoExpectedStatus) if !exists { - assert.EqualValues(t, http.StatusNotFound, resp.Code) + assert.Equal(t, http.StatusNotFound, resp.Code) return } - assert.EqualValues(t, http.StatusOK, resp.Code) + assert.Equal(t, http.StatusOK, resp.Code) var branch api.Branch DecodeJSON(t, resp, &branch) - assert.EqualValues(t, branchName, branch.Name) + assert.Equal(t, branchName, branch.Name) assert.True(t, branch.UserCanPush) assert.True(t, branch.UserCanMerge) } @@ -44,7 +44,7 @@ func testAPIGetBranchProtection(t *testing.T, branchName string, expectedHTTPSta if resp.Code == http.StatusOK { var branchProtection api.BranchProtection DecodeJSON(t, resp, &branchProtection) - assert.EqualValues(t, branchName, branchProtection.RuleName) + assert.Equal(t, branchName, branchProtection.RuleName) return &branchProtection } return nil @@ -60,7 +60,7 @@ func testAPICreateBranchProtection(t *testing.T, branchName string, expectedPrio if resp.Code == http.StatusCreated { var branchProtection api.BranchProtection DecodeJSON(t, resp, &branchProtection) - assert.EqualValues(t, branchName, branchProtection.RuleName) + assert.Equal(t, branchName, branchProtection.RuleName) assert.EqualValues(t, expectedPriority, branchProtection.Priority) } } @@ -74,7 +74,7 @@ func testAPIEditBranchProtection(t *testing.T, branchName string, body *api.Bran if resp.Code == http.StatusOK { var branchProtection api.BranchProtection DecodeJSON(t, resp, &branchProtection) - assert.EqualValues(t, branchName, branchProtection.RuleName) + assert.Equal(t, branchName, branchProtection.RuleName) } } @@ -181,7 +181,7 @@ func testAPICreateBranch(t testing.TB, session *TestSession, user, repo, oldBran DecodeJSON(t, resp, &branch) if resp.Result().StatusCode == http.StatusCreated { - assert.EqualValues(t, newBranch, branch.Name) + assert.Equal(t, newBranch, branch.Name) } return resp.Result().StatusCode == status @@ -303,7 +303,7 @@ func TestAPICreateBranchWithSyncBranches(t *testing.T) { RepoID: 1, }) assert.NoError(t, err) - assert.Len(t, branches, 4) + assert.Len(t, branches, 6) // make a broke repository with no branch on database _, err = db.DeleteByBean(db.DefaultContext, git_model.Branch{RepoID: 1}) @@ -320,7 +320,7 @@ func TestAPICreateBranchWithSyncBranches(t *testing.T) { RepoID: 1, }) assert.NoError(t, err) - assert.Len(t, branches, 5) + assert.Len(t, branches, 7) branches, err = db.Find[git_model.Branch](db.DefaultContext, git_model.FindBranchOptions{ RepoID: 1, diff --git a/tests/integration/api_comment_test.go b/tests/integration/api_comment_test.go index 255b8332b2..9842c358f6 100644 --- a/tests/integration/api_comment_test.go +++ b/tests/integration/api_comment_test.go @@ -106,7 +106,7 @@ func TestAPICreateComment(t *testing.T) { var updatedComment api.Comment DecodeJSON(t, resp, &updatedComment) - assert.EqualValues(t, commentBody, updatedComment.Body) + assert.Equal(t, commentBody, updatedComment.Body) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: updatedComment.ID, IssueID: issue.ID, Content: commentBody}) t.Run("BlockedByRepoOwner", func(t *testing.T) { @@ -174,7 +174,7 @@ func TestAPIGetSystemUserComment(t *testing.T) { user_model.NewGhostUser(), user_model.NewActionsUser(), } { - body := fmt.Sprintf("Hello %s", systemUser.Name) + body := "Hello " + systemUser.Name comment, err := issues_model.CreateComment(db.DefaultContext, &issues_model.CreateCommentOptions{ Type: issues_model.CommentTypeComment, Doer: systemUser, @@ -233,8 +233,8 @@ func TestAPIEditComment(t *testing.T) { var updatedComment api.Comment DecodeJSON(t, resp, &updatedComment) - assert.EqualValues(t, comment.ID, updatedComment.ID) - assert.EqualValues(t, newCommentBody, updatedComment.Body) + assert.Equal(t, comment.ID, updatedComment.ID) + assert.Equal(t, newCommentBody, updatedComment.Body) unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: comment.ID, IssueID: issue.ID, Content: newCommentBody}) } diff --git a/tests/integration/api_fork_test.go b/tests/integration/api_fork_test.go index 69f37f4574..2837c3b93e 100644 --- a/tests/integration/api_fork_test.go +++ b/tests/integration/api_fork_test.go @@ -34,7 +34,7 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { // fork into a limited org limitedOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 22}) - assert.EqualValues(t, api.VisibleTypeLimited, limitedOrg.Visibility) + assert.Equal(t, api.VisibleTypeLimited, limitedOrg.Visibility) ownerTeam1, err := org_model.OrgFromUser(limitedOrg).GetOwnerTeam(db.DefaultContext) assert.NoError(t, err) @@ -49,7 +49,7 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { user4Sess := loginUser(t, "user4") user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user4"}) privateOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23}) - assert.EqualValues(t, api.VisibleTypePrivate, privateOrg.Visibility) + assert.Equal(t, api.VisibleTypePrivate, privateOrg.Visibility) ownerTeam2, err := org_model.OrgFromUser(privateOrg).GetOwnerTeam(db.DefaultContext) assert.NoError(t, err) @@ -70,7 +70,7 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { DecodeJSON(t, resp, &forks) assert.Empty(t, forks) - assert.EqualValues(t, "0", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "0", resp.Header().Get("X-Total-Count")) }) t.Run("Logged in", func(t *testing.T) { @@ -83,7 +83,7 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { DecodeJSON(t, resp, &forks) assert.Len(t, forks, 2) - assert.EqualValues(t, "2", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "2", resp.Header().Get("X-Total-Count")) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user1)) @@ -94,7 +94,7 @@ func TestAPIForkListLimitedAndPrivateRepos(t *testing.T) { DecodeJSON(t, resp, &forks) assert.Len(t, forks, 2) - assert.EqualValues(t, "2", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "2", resp.Header().Get("X-Total-Count")) }) } @@ -121,7 +121,7 @@ func TestGetPrivateReposForks(t *testing.T) { forks := []*api.Repository{} DecodeJSON(t, resp, &forks) assert.Len(t, forks, 1) - assert.EqualValues(t, "1", resp.Header().Get("X-Total-Count")) - assert.EqualValues(t, "forked-repo", forks[0].Name) - assert.EqualValues(t, privateOrg.Name, forks[0].Owner.UserName) + assert.Equal(t, "1", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "forked-repo", forks[0].Name) + assert.Equal(t, privateOrg.Name, forks[0].Owner.UserName) } diff --git a/tests/integration/api_gitignore_templates_test.go b/tests/integration/api_gitignore_templates_test.go index c58f5eebfe..1c56d51344 100644 --- a/tests/integration/api_gitignore_templates_test.go +++ b/tests/integration/api_gitignore_templates_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "testing" @@ -38,7 +37,7 @@ func TestAPIGetGitignoreTemplateInfo(t *testing.T) { // Use the first template for the test templateName := repo_module.Gitignores[0] - urlStr := fmt.Sprintf("/api/v1/gitignore/templates/%s", templateName) + urlStr := "/api/v1/gitignore/templates/" + templateName req := NewRequest(t, "GET", urlStr) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_gpg_keys_test.go b/tests/integration/api_gpg_keys_test.go index ec0dafc2d6..edfb9e6eca 100644 --- a/tests/integration/api_gpg_keys_test.go +++ b/tests/integration/api_gpg_keys_test.go @@ -86,13 +86,13 @@ func TestGPGKeys(t *testing.T) { assert.Len(t, keys, 1) primaryKey1 := keys[0] // Primary key 1 - assert.EqualValues(t, "38EA3BCED732982C", primaryKey1.KeyID) + assert.Equal(t, "38EA3BCED732982C", primaryKey1.KeyID) assert.Len(t, primaryKey1.Emails, 1) - assert.EqualValues(t, "user2@example.com", primaryKey1.Emails[0].Email) + assert.Equal(t, "user2@example.com", primaryKey1.Emails[0].Email) assert.True(t, primaryKey1.Emails[0].Verified) subKey := primaryKey1.SubsKey[0] // Subkey of 38EA3BCED732982C - assert.EqualValues(t, "70D7C694D17D03AD", subKey.KeyID) + assert.Equal(t, "70D7C694D17D03AD", subKey.KeyID) assert.Empty(t, subKey.Emails) var key api.GPGKey @@ -100,16 +100,16 @@ func TestGPGKeys(t *testing.T) { AddTokenAuth(tokenWithGPGKeyScope) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &key) - assert.EqualValues(t, "38EA3BCED732982C", key.KeyID) + assert.Equal(t, "38EA3BCED732982C", key.KeyID) assert.Len(t, key.Emails, 1) - assert.EqualValues(t, "user2@example.com", key.Emails[0].Email) + assert.Equal(t, "user2@example.com", key.Emails[0].Email) assert.True(t, key.Emails[0].Verified) req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)). // Subkey of 38EA3BCED732982C AddTokenAuth(tokenWithGPGKeyScope) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &key) - assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID) + assert.Equal(t, "70D7C694D17D03AD", key.KeyID) assert.Empty(t, key.Emails) }) diff --git a/tests/integration/api_helper_for_declarative_test.go b/tests/integration/api_helper_for_declarative_test.go index f3a595540f..083535a9a5 100644 --- a/tests/integration/api_helper_for_declarative_test.go +++ b/tests/integration/api_helper_for_declarative_test.go @@ -276,7 +276,7 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) } err := api.APIError{} DecodeJSON(t, resp, &err) - assert.EqualValues(t, "Please try again later", err.Message) + assert.Equal(t, "Please try again later", err.Message) queue.GetManager().FlushAll(t.Context(), 5*time.Second) <-time.After(1 * time.Second) } @@ -286,7 +286,7 @@ func doAPIMergePullRequest(ctx APITestContext, owner, repo string, index int64) expected = http.StatusOK } - if !assert.EqualValues(t, expected, resp.Code, + if !assert.Equal(t, expected, resp.Code, "Request: %s %s", req.Method, req.URL.String()) { logUnexpectedResponse(t, resp) } diff --git a/tests/integration/api_issue_label_test.go b/tests/integration/api_issue_label_test.go index c9cdd46b9a..4324fd37d9 100644 --- a/tests/integration/api_issue_label_test.go +++ b/tests/integration/api_issue_label_test.go @@ -38,8 +38,8 @@ func TestAPIModifyLabels(t *testing.T) { apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) 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) + assert.Equal(t, dbLabel.Name, apiLabel.Name) + assert.Equal(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) req = NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "TestL 2", @@ -67,7 +67,7 @@ func TestAPIModifyLabels(t *testing.T) { AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) - assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) + assert.Equal(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) // EditLabel newName := "LabelNewName" @@ -79,7 +79,7 @@ func TestAPIModifyLabels(t *testing.T) { }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) - assert.EqualValues(t, newColor, apiLabel.Color) + assert.Equal(t, newColor, apiLabel.Color) req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Color: &newColorWrong, }).AddTokenAuth(token) @@ -165,7 +165,7 @@ func TestAPIReplaceIssueLabels(t *testing.T) { var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) if assert.Len(t, apiLabels, 1) { - assert.EqualValues(t, label.ID, apiLabels[0].ID) + assert.Equal(t, label.ID, apiLabels[0].ID) } unittest.AssertCount(t, &issues_model.IssueLabel{IssueID: issue.ID}, 1) @@ -191,7 +191,7 @@ func TestAPIReplaceIssueLabelsWithLabelNames(t *testing.T) { var apiLabels []*api.Label DecodeJSON(t, resp, &apiLabels) if assert.Len(t, apiLabels, 1) { - assert.EqualValues(t, label.Name, apiLabels[0].Name) + assert.Equal(t, label.Name, apiLabels[0].Name) } } @@ -215,8 +215,8 @@ func TestAPIModifyOrgLabels(t *testing.T) { apiLabel := new(api.Label) DecodeJSON(t, resp, &apiLabel) 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) + assert.Equal(t, dbLabel.Name, apiLabel.Name) + assert.Equal(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) req = NewRequestWithJSON(t, "POST", urlStr, &api.CreateLabelOption{ Name: "TestL 2", @@ -244,7 +244,7 @@ func TestAPIModifyOrgLabels(t *testing.T) { AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) - assert.EqualValues(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) + assert.Equal(t, strings.TrimLeft(dbLabel.Color, "#"), apiLabel.Color) // EditLabel newName := "LabelNewName" @@ -256,7 +256,7 @@ func TestAPIModifyOrgLabels(t *testing.T) { }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiLabel) - assert.EqualValues(t, newColor, apiLabel.Color) + assert.Equal(t, newColor, apiLabel.Color) req = NewRequestWithJSON(t, "PATCH", singleURLStr, &api.EditLabelOption{ Color: &newColorWrong, }).AddTokenAuth(token) diff --git a/tests/integration/api_issue_milestone_test.go b/tests/integration/api_issue_milestone_test.go index 2d00752302..1196c8d358 100644 --- a/tests/integration/api_issue_milestone_test.go +++ b/tests/integration/api_issue_milestone_test.go @@ -73,7 +73,7 @@ func TestAPIIssuesMilestone(t *testing.T) { AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiMilestone) - assert.EqualValues(t, apiMilestones[2], apiMilestone) + assert.Equal(t, apiMilestones[2], apiMilestone) req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/milestones?state=%s&name=%s", owner.Name, repo.Name, "all", "milestone2")). AddTokenAuth(token) diff --git a/tests/integration/api_issue_stopwatch_test.go b/tests/integration/api_issue_stopwatch_test.go index 4765787e6f..3606d9a228 100644 --- a/tests/integration/api_issue_stopwatch_test.go +++ b/tests/integration/api_issue_stopwatch_test.go @@ -35,11 +35,11 @@ func TestAPIListStopWatches(t *testing.T) { 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) - assert.EqualValues(t, issue.Title, apiWatches[0].IssueTitle) - assert.EqualValues(t, repo.Name, apiWatches[0].RepoName) - assert.EqualValues(t, repo.OwnerName, apiWatches[0].RepoOwnerName) + assert.Equal(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) + assert.Equal(t, issue.Index, apiWatches[0].IssueIndex) + assert.Equal(t, issue.Title, apiWatches[0].IssueTitle) + assert.Equal(t, repo.Name, apiWatches[0].RepoName) + assert.Equal(t, repo.OwnerName, apiWatches[0].RepoOwnerName) assert.Positive(t, apiWatches[0].Seconds) } } diff --git a/tests/integration/api_issue_subscription_test.go b/tests/integration/api_issue_subscription_test.go index 7a716301c4..74ba171c01 100644 --- a/tests/integration/api_issue_subscription_test.go +++ b/tests/integration/api_issue_subscription_test.go @@ -43,11 +43,11 @@ func TestAPIIssueSubscriptions(t *testing.T) { wi := new(api.WatchInfo) DecodeJSON(t, resp, wi) - assert.EqualValues(t, isWatching, wi.Subscribed) - assert.EqualValues(t, !isWatching, wi.Ignored) - assert.EqualValues(t, issue.APIURL(db.DefaultContext)+"/subscriptions", wi.URL) + assert.Equal(t, isWatching, wi.Subscribed) + assert.Equal(t, !isWatching, wi.Ignored) + assert.Equal(t, issue.APIURL(db.DefaultContext)+"/subscriptions", wi.URL) assert.EqualValues(t, issue.CreatedUnix, wi.CreatedAt.Unix()) - assert.EqualValues(t, issueRepo.APIURL(), wi.RepositoryURL) + assert.Equal(t, issueRepo.APIURL(), wi.RepositoryURL) } testSubscription(issue1, true) diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go index d8394a33d9..e035f7200b 100644 --- a/tests/integration/api_issue_test.go +++ b/tests/integration/api_issue_test.go @@ -313,7 +313,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "10") @@ -321,7 +321,7 @@ func TestAPISearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 10) query = url.Values{"assigned": {"true"}, "state": {"all"}} diff --git a/tests/integration/api_issue_tracked_time_test.go b/tests/integration/api_issue_tracked_time_test.go index fd2c452b20..bd562b602e 100644 --- a/tests/integration/api_issue_tracked_time_test.go +++ b/tests/integration/api_issue_tracked_time_test.go @@ -41,8 +41,8 @@ func TestAPIGetTrackedTimes(t *testing.T) { for i, time := range expect { assert.Equal(t, time.ID, apiTimes[i].ID) - assert.EqualValues(t, issue2.Title, apiTimes[i].Issue.Title) - assert.EqualValues(t, issue2.ID, apiTimes[i].IssueID) + assert.Equal(t, issue2.Title, apiTimes[i].Issue.Title) + assert.Equal(t, issue2.ID, apiTimes[i].IssueID) assert.Equal(t, time.Created.Unix(), apiTimes[i].Created.Unix()) assert.Equal(t, time.Time, apiTimes[i].Time) user, err := user_model.GetUserByID(db.DefaultContext, time.UserID) @@ -125,6 +125,6 @@ func TestAPIAddTrackedTimes(t *testing.T) { DecodeJSON(t, resp, &apiNewTime) assert.EqualValues(t, 33, apiNewTime.Time) - assert.EqualValues(t, user2.ID, apiNewTime.UserID) + assert.Equal(t, user2.ID, apiNewTime.UserID) assert.EqualValues(t, 947688818, apiNewTime.Created.Unix()) } diff --git a/tests/integration/api_keys_test.go b/tests/integration/api_keys_test.go index 2276b955cf..3162051acc 100644 --- a/tests/integration/api_keys_test.go +++ b/tests/integration/api_keys_test.go @@ -143,7 +143,7 @@ func TestCreateUserKey(t *testing.T) { }) // Search by fingerprint - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). + req = NewRequest(t, "GET", "/api/v1/user/keys?fingerprint="+newPublicKey.Fingerprint). AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) @@ -183,7 +183,7 @@ func TestCreateUserKey(t *testing.T) { token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser) // Should find key even though not ours, but we shouldn't know whose it is - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). + req = NewRequest(t, "GET", "/api/v1/user/keys?fingerprint="+newPublicKey.Fingerprint). AddTokenAuth(token2) resp = MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_label_templates_test.go b/tests/integration/api_label_templates_test.go index 007e979011..3e637daba6 100644 --- a/tests/integration/api_label_templates_test.go +++ b/tests/integration/api_label_templates_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "net/url" "strings" @@ -42,7 +41,7 @@ func TestAPIGetLabelTemplateInfo(t *testing.T) { // Use the first template for the test templateName := repo_module.LabelTemplateFiles[0].DisplayName - urlStr := fmt.Sprintf("/api/v1/label/templates/%s", url.PathEscape(templateName)) + urlStr := "/api/v1/label/templates/" + url.PathEscape(templateName) req := NewRequest(t, "GET", urlStr) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_license_templates_test.go b/tests/integration/api_license_templates_test.go index e12aab7c2c..52e240f9a7 100644 --- a/tests/integration/api_license_templates_test.go +++ b/tests/integration/api_license_templates_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "net/url" "testing" @@ -39,7 +38,7 @@ func TestAPIGetLicenseTemplateInfo(t *testing.T) { // Use the first template for the test licenseName := repo_module.Licenses[0] - urlStr := fmt.Sprintf("/api/v1/licenses/%s", url.PathEscape(licenseName)) + urlStr := "/api/v1/licenses/" + url.PathEscape(licenseName) req := NewRequest(t, "GET", urlStr) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_notification_test.go b/tests/integration/api_notification_test.go index dc4ba83ecc..e6bc142476 100644 --- a/tests/integration/api_notification_test.go +++ b/tests/integration/api_notification_test.go @@ -35,7 +35,7 @@ func TestAPINotification(t *testing.T) { // -- GET /notifications -- // test filter since := "2000-01-01T00%3A50%3A01%2B00%3A00" // 946687801 - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/notifications?since=%s", since)). + req := NewRequest(t, "GET", "/api/v1/notifications?since="+since). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) var apiNL []api.NotificationThread @@ -104,10 +104,10 @@ func TestAPINotification(t *testing.T) { assert.EqualValues(t, 5, apiN.ID) assert.False(t, apiN.Pinned) assert.True(t, apiN.Unread) - assert.EqualValues(t, "issue4", apiN.Subject.Title) + assert.Equal(t, "issue4", apiN.Subject.Title) assert.EqualValues(t, "Issue", apiN.Subject.Type) - assert.EqualValues(t, thread5.Issue.APIURL(db.DefaultContext), apiN.Subject.URL) - assert.EqualValues(t, thread5.Repository.HTMLURL(), apiN.Repository.HTMLURL) + assert.Equal(t, thread5.Issue.APIURL(db.DefaultContext), apiN.Subject.URL) + assert.Equal(t, thread5.Repository.HTMLURL(), apiN.Repository.HTMLURL) MakeRequest(t, NewRequest(t, "GET", "/api/v1/notifications/new"), http.StatusUnauthorized) diff --git a/tests/integration/api_oauth2_apps_test.go b/tests/integration/api_oauth2_apps_test.go index 7a17b4ca88..13f64fd69e 100644 --- a/tests/integration/api_oauth2_apps_test.go +++ b/tests/integration/api_oauth2_apps_test.go @@ -43,12 +43,12 @@ func testAPICreateOAuth2Application(t *testing.T) { var createdApp *api.OAuth2Application DecodeJSON(t, resp, &createdApp) - assert.EqualValues(t, appBody.Name, createdApp.Name) + assert.Equal(t, appBody.Name, createdApp.Name) assert.Len(t, createdApp.ClientSecret, 56) assert.Len(t, createdApp.ClientID, 36) assert.True(t, createdApp.ConfidentialClient) assert.NotEmpty(t, createdApp.Created) - assert.EqualValues(t, appBody.RedirectURIs[0], createdApp.RedirectURIs[0]) + assert.Equal(t, appBody.RedirectURIs[0], createdApp.RedirectURIs[0]) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{UID: user.ID, Name: createdApp.Name}) } @@ -74,12 +74,12 @@ func testAPIListOAuth2Applications(t *testing.T) { DecodeJSON(t, resp, &appList) expectedApp := appList[0] - assert.EqualValues(t, expectedApp.Name, existApp.Name) - assert.EqualValues(t, expectedApp.ClientID, existApp.ClientID) + assert.Equal(t, expectedApp.Name, existApp.Name) + assert.Equal(t, expectedApp.ClientID, existApp.ClientID) assert.Equal(t, expectedApp.ConfidentialClient, existApp.ConfidentialClient) assert.Len(t, expectedApp.ClientID, 36) assert.Empty(t, expectedApp.ClientSecret) - assert.EqualValues(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0]) + assert.Equal(t, existApp.RedirectURIs[0], expectedApp.RedirectURIs[0]) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name}) } @@ -128,13 +128,13 @@ func testAPIGetOAuth2Application(t *testing.T) { DecodeJSON(t, resp, &app) expectedApp := app - assert.EqualValues(t, expectedApp.Name, existApp.Name) - assert.EqualValues(t, expectedApp.ClientID, existApp.ClientID) + assert.Equal(t, expectedApp.Name, existApp.Name) + assert.Equal(t, expectedApp.ClientID, existApp.ClientID) assert.Equal(t, expectedApp.ConfidentialClient, existApp.ConfidentialClient) assert.Len(t, expectedApp.ClientID, 36) assert.Empty(t, expectedApp.ClientSecret) assert.Len(t, expectedApp.RedirectURIs, 1) - assert.EqualValues(t, expectedApp.RedirectURIs[0], existApp.RedirectURIs[0]) + assert.Equal(t, expectedApp.RedirectURIs[0], existApp.RedirectURIs[0]) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name}) } @@ -168,8 +168,8 @@ func testAPIUpdateOAuth2Application(t *testing.T) { expectedApp := app assert.Len(t, expectedApp.RedirectURIs, 2) - assert.EqualValues(t, expectedApp.RedirectURIs[0], appBody.RedirectURIs[0]) - assert.EqualValues(t, expectedApp.RedirectURIs[1], appBody.RedirectURIs[1]) + assert.Equal(t, expectedApp.RedirectURIs[0], appBody.RedirectURIs[0]) + assert.Equal(t, expectedApp.RedirectURIs[1], appBody.RedirectURIs[1]) assert.Equal(t, expectedApp.ConfidentialClient, appBody.ConfidentialClient) unittest.AssertExistsAndLoadBean(t, &auth_model.OAuth2Application{ID: expectedApp.ID, Name: expectedApp.Name}) } diff --git a/tests/integration/api_org_test.go b/tests/integration/api_org_test.go index d766b1e8be..46b96dc7c1 100644 --- a/tests/integration/api_org_test.go +++ b/tests/integration/api_org_test.go @@ -59,7 +59,7 @@ func TestAPIOrgCreateRename(t *testing.T) { req = NewRequestf(t, "GET", "/api/v1/orgs/%s", org.UserName).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiOrg) - assert.EqualValues(t, org.UserName, apiOrg.Name) + assert.Equal(t, org.UserName, apiOrg.Name) t.Run("CheckPermission", func(t *testing.T) { // Check owner team permission @@ -86,7 +86,7 @@ func TestAPIOrgCreateRename(t *testing.T) { var users []*api.User DecodeJSON(t, resp, &users) assert.Len(t, users, 1) - assert.EqualValues(t, "user1", users[0].UserName) + assert.Equal(t, "user1", users[0].UserName) }) t.Run("RenameOrg", func(t *testing.T) { @@ -156,7 +156,7 @@ func TestAPIOrgEditBadVisibility(t *testing.T) { func TestAPIOrgDeny(t *testing.T) { defer tests.PrepareTestEnv(t)() - defer test.MockVariableValue(&setting.Service.RequireSignInView, true)() + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() orgName := "user1_org" req := NewRequestf(t, "GET", "/api/v1/orgs/%s", orgName) @@ -225,6 +225,6 @@ func TestAPIOrgSearchEmptyTeam(t *testing.T) { DecodeJSON(t, resp, &data) assert.True(t, data.Ok) if assert.Len(t, data.Data, 1) { - assert.EqualValues(t, "Empty", data.Data[0].Name) + assert.Equal(t, "Empty", data.Data[0].Name) } } diff --git a/tests/integration/api_packages_arch_test.go b/tests/integration/api_packages_arch_test.go index b9064ca3d1..e5778b4203 100644 --- a/tests/integration/api_packages_arch_test.go +++ b/tests/integration/api_packages_arch_test.go @@ -163,7 +163,7 @@ license = MIT`) assert.Condition(t, func() bool { seen := false expectedFilename := fmt.Sprintf("%s-%s-aarch64.pkg.tar.%s", packageName, packageVersion, compression) - expectedCompositeKey := fmt.Sprintf("%s|aarch64", repository) + expectedCompositeKey := repository + "|aarch64" for _, pf := range pfs { if pf.Name == expectedFilename && pf.CompositeKey == expectedCompositeKey { if seen { @@ -321,7 +321,7 @@ license = MIT`) _, has = content["gitea-test-1.0.1/desc"] assert.True(t, has) - req = NewRequest(t, "DELETE", fmt.Sprintf("%s/gitea-test/1.0.1/aarch64", rootURL)). + req = NewRequest(t, "DELETE", rootURL+"/gitea-test/1.0.1/aarch64"). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNoContent) diff --git a/tests/integration/api_packages_cargo_test.go b/tests/integration/api_packages_cargo_test.go index 3fb9687653..8b5caa7ea7 100644 --- a/tests/integration/api_packages_cargo_test.go +++ b/tests/integration/api_packages_cargo_test.go @@ -94,7 +94,7 @@ func testPackageCargo(t *testing.T, _ *neturl.URL) { } root := fmt.Sprintf("%sapi/packages/%s/cargo", setting.AppURL, user.Name) - url := fmt.Sprintf("%s/api/v1/crates", root) + url := root + "/api/v1/crates" t.Run("Index", func(t *testing.T) { t.Run("Git/Config", func(t *testing.T) { diff --git a/tests/integration/api_packages_chef_test.go b/tests/integration/api_packages_chef_test.go index 6efb2708af..86b3be9d0c 100644 --- a/tests/integration/api_packages_chef_test.go +++ b/tests/integration/api_packages_chef_test.go @@ -274,7 +274,7 @@ nwIDAQAB uploadPackage := func(t *testing.T, version string, expectedStatus int) { var body bytes.Buffer mpw := multipart.NewWriter(&body) - part, _ := mpw.CreateFormFile("tarball", fmt.Sprintf("%s.tar.gz", version)) + part, _ := mpw.CreateFormFile("tarball", version+".tar.gz") zw := gzip.NewWriter(part) tw := tar.NewWriter(zw) @@ -320,7 +320,7 @@ nwIDAQAB pfs, err := packages.GetFilesByVersionID(db.DefaultContext, pvs[0].ID) assert.NoError(t, err) assert.Len(t, pfs, 1) - assert.Equal(t, fmt.Sprintf("%s.tar.gz", packageVersion), pfs[0].Name) + assert.Equal(t, packageVersion+".tar.gz", pfs[0].Name) assert.True(t, pfs[0].IsLead) uploadPackage(t, packageVersion, http.StatusConflict) diff --git a/tests/integration/api_packages_composer_test.go b/tests/integration/api_packages_composer_test.go index bc858c7476..54f61d91d9 100644 --- a/tests/integration/api_packages_composer_test.go +++ b/tests/integration/api_packages_composer_test.go @@ -64,7 +64,7 @@ func TestPackageComposer(t *testing.T) { t.Run("ServiceIndex", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/packages.json", url)). + req := NewRequest(t, "GET", url+"/packages.json"). AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_packages_conan_test.go b/tests/integration/api_packages_conan_test.go index 3055e57a2e..4e83c998b8 100644 --- a/tests/integration/api_packages_conan_test.go +++ b/tests/integration/api_packages_conan_test.go @@ -91,18 +91,18 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)). + req = NewRequest(t, "GET", recipeURL+"/digest"). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)). + req = NewRequest(t, "GET", recipeURL+"/download_urls"). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL)) + req = NewRequest(t, "POST", recipeURL+"/upload_urls") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL), map[string]int64{ + req = NewRequestWithJSON(t, "POST", recipeURL+"/upload_urls", map[string]int64{ conanfileName: int64(len(contentConanfile)), "removed.txt": 0, }).AddTokenAuth(token) @@ -127,18 +127,18 @@ func uploadConanPackageV1(t *testing.T, baseURL, token, name, version, user, cha AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)). + req = NewRequest(t, "GET", packageURL+"/digest"). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)). + req = NewRequest(t, "GET", packageURL+"/download_urls"). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL)) + req = NewRequest(t, "POST", packageURL+"/upload_urls") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", packageURL), map[string]int64{ + req = NewRequestWithJSON(t, "POST", packageURL+"/upload_urls", map[string]int64{ conaninfoName: int64(len(contentConaninfo)), "removed.txt": 0, }).AddTokenAuth(token) @@ -167,7 +167,7 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", recipeURL)). + req = NewRequest(t, "GET", recipeURL+"/files"). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) @@ -180,7 +180,7 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha packageURL := fmt.Sprintf("%s/packages/%s/revisions/%s", recipeURL, conanPackageReference, packageRevision) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)). + req = NewRequest(t, "GET", packageURL+"/files"). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) @@ -188,7 +188,7 @@ func uploadConanPackageV2(t *testing.T, baseURL, token, name, version, user, cha AddTokenAuth(token) MakeRequest(t, req, http.StatusCreated) - req = NewRequest(t, "GET", fmt.Sprintf("%s/files", packageURL)). + req = NewRequest(t, "GET", packageURL+"/files"). AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) @@ -219,7 +219,7 @@ func TestPackageConan(t *testing.T) { t.Run("Ping", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/ping", url)) + req := NewRequest(t, "GET", url+"/v1/ping") resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "revisions", resp.Header().Get("X-Conan-Server-Capabilities")) @@ -230,7 +230,7 @@ func TestPackageConan(t *testing.T) { t.Run("UserName/Password Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)). + req := NewRequest(t, "GET", url+"/v1/users/authenticate"). AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) @@ -256,7 +256,7 @@ func TestPackageConan(t *testing.T) { token := getTokenForLoggedInUser(t, session, scope) - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/authenticate", url)). + req := NewRequest(t, "GET", url+"/v1/users/authenticate"). AddTokenAuth(token) resp := MakeRequest(t, req, expectedAuthStatusCode) if expectedAuthStatusCode != http.StatusOK { @@ -273,7 +273,7 @@ func TestPackageConan(t *testing.T) { recipeURL := fmt.Sprintf("%s/v1/conans/%s/%s/%s/%s", url, "TestScope", version1, "testing", channel1) - req = NewRequestWithJSON(t, "POST", fmt.Sprintf("%s/upload_urls", recipeURL), map[string]int64{ + req = NewRequestWithJSON(t, "POST", recipeURL+"/upload_urls", map[string]int64{ conanfileName: 64, "removed.txt": 0, }).AddTokenAuth(token) @@ -308,7 +308,7 @@ func TestPackageConan(t *testing.T) { t.Run("CheckCredentials", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v1/users/check_credentials", url)). + req := NewRequest(t, "GET", url+"/v1/users/check_credentials"). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) }) @@ -356,7 +356,7 @@ func TestPackageConan(t *testing.T) { assert.Equal(t, int64(len(contentConaninfo)), pb.Size) } else { - assert.FailNow(t, "unknown file: %s", pf.Name) + assert.FailNow(t, "unknown file", "unknown file: %s", pf.Name) } } }) @@ -376,14 +376,14 @@ func TestPackageConan(t *testing.T) { assert.Contains(t, fileHashes, conanfileName) assert.Equal(t, "7abc52241c22090782c54731371847a8", fileHashes[conanfileName]) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", recipeURL)) + req = NewRequest(t, "GET", recipeURL+"/digest") resp = MakeRequest(t, req, http.StatusOK) downloadURLs := make(map[string]string) DecodeJSON(t, resp, &downloadURLs) assert.Contains(t, downloadURLs, conanfileName) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", recipeURL)) + req = NewRequest(t, "GET", recipeURL+"/download_urls") resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &downloadURLs) @@ -404,14 +404,14 @@ func TestPackageConan(t *testing.T) { assert.Contains(t, fileHashes, conaninfoName) assert.Equal(t, "7628bfcc5b17f1470c468621a78df394", fileHashes[conaninfoName]) - req = NewRequest(t, "GET", fmt.Sprintf("%s/digest", packageURL)) + req = NewRequest(t, "GET", packageURL+"/digest") resp = MakeRequest(t, req, http.StatusOK) downloadURLs = make(map[string]string) DecodeJSON(t, resp, &downloadURLs) assert.Contains(t, downloadURLs, conaninfoName) - req = NewRequest(t, "GET", fmt.Sprintf("%s/download_urls", packageURL)) + req = NewRequest(t, "GET", packageURL+"/download_urls") resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &downloadURLs) @@ -550,7 +550,7 @@ func TestPackageConan(t *testing.T) { t.Run("Ping", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/ping", url)) + req := NewRequest(t, "GET", url+"/v2/ping") resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "revisions", resp.Header().Get("X-Conan-Server-Capabilities")) @@ -561,7 +561,7 @@ func TestPackageConan(t *testing.T) { t.Run("UserName/Password Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)). + req := NewRequest(t, "GET", url+"/v2/users/authenticate"). AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) @@ -573,7 +573,7 @@ func TestPackageConan(t *testing.T) { assert.Equal(t, user.ID, pkgMeta.UserID) assert.Equal(t, auth_model.AccessTokenScopeAll, pkgMeta.Scope) - token = fmt.Sprintf("Bearer %s", body) + token = "Bearer " + body }) badToken := "" @@ -590,7 +590,7 @@ func TestPackageConan(t *testing.T) { token := getTokenForLoggedInUser(t, session, scope) - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/authenticate", url)). + req := NewRequest(t, "GET", url+"/v2/users/authenticate"). AddTokenAuth(token) resp := MakeRequest(t, req, expectedAuthStatusCode) if expectedAuthStatusCode != http.StatusOK { @@ -640,7 +640,7 @@ func TestPackageConan(t *testing.T) { t.Run("CheckCredentials", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/v2/users/check_credentials", url)). + req := NewRequest(t, "GET", url+"/v2/users/check_credentials"). AddTokenAuth(token) MakeRequest(t, req, http.StatusOK) }) @@ -664,7 +664,7 @@ func TestPackageConan(t *testing.T) { recipeURL := fmt.Sprintf("%s/v2/conans/%s/%s/%s/%s", url, name, version1, user1, channel1) - req := NewRequest(t, "GET", fmt.Sprintf("%s/latest", recipeURL)) + req := NewRequest(t, "GET", recipeURL+"/latest") resp := MakeRequest(t, req, http.StatusOK) obj := make(map[string]string) diff --git a/tests/integration/api_packages_conda_test.go b/tests/integration/api_packages_conda_test.go index 272a660d45..32f55e5435 100644 --- a/tests/integration/api_packages_conda_test.go +++ b/tests/integration/api_packages_conda_test.go @@ -193,19 +193,19 @@ func TestPackageConda(t *testing.T) { Removed map[string]*PackageInfo `json:"removed"` } - req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/repodata.json", root)) + req := NewRequest(t, "GET", root+"/noarch/repodata.json") resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "application/json", resp.Header().Get("Content-Type")) - req = NewRequest(t, "GET", fmt.Sprintf("%s/noarch/repodata.json.bz2", root)) + req = NewRequest(t, "GET", root+"/noarch/repodata.json.bz2") resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type")) - req = NewRequest(t, "GET", fmt.Sprintf("%s/noarch/current_repodata.json", root)) + req = NewRequest(t, "GET", root+"/noarch/current_repodata.json") resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, "application/json", resp.Header().Get("Content-Type")) - req = NewRequest(t, "GET", fmt.Sprintf("%s/noarch/current_repodata.json.bz2", root)) + req = NewRequest(t, "GET", root+"/noarch/current_repodata.json.bz2") resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, "application/x-bzip2", resp.Header().Get("Content-Type")) @@ -218,7 +218,7 @@ func TestPackageConda(t *testing.T) { pd, err := packages.GetPackageDescriptor(db.DefaultContext, pv) assert.NoError(t, err) - req := NewRequest(t, "GET", fmt.Sprintf("%s/noarch/repodata.json", root)) + req := NewRequest(t, "GET", root+"/noarch/repodata.json") resp := MakeRequest(t, req, http.StatusOK) var result RepoData diff --git a/tests/integration/api_packages_container_test.go b/tests/integration/api_packages_container_test.go index 3905ad1b70..b2db77685d 100644 --- a/tests/integration/api_packages_container_test.go +++ b/tests/integration/api_packages_container_test.go @@ -9,6 +9,7 @@ import ( "encoding/base64" "fmt" "net/http" + "strconv" "strings" "sync" "testing" @@ -92,12 +93,12 @@ func TestPackageContainer(t *testing.T) { t.Run("Anonymous", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) + req := NewRequest(t, "GET", setting.AppURL+"v2") resp := MakeRequest(t, req, http.StatusUnauthorized) assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate")) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req = NewRequest(t, "GET", setting.AppURL+"v2/token") resp = MakeRequest(t, req, http.StatusOK) tokenResponse := &TokenResponse{} @@ -105,18 +106,18 @@ func TestPackageContainer(t *testing.T) { assert.NotEmpty(t, tokenResponse.Token) - anonymousToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) + anonymousToken = "Bearer " + tokenResponse.Token - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + req = NewRequest(t, "GET", setting.AppURL+"v2"). AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusOK) - defer test.MockVariableValue(&setting.Service.RequireSignInView, true)() + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) + req = NewRequest(t, "GET", setting.AppURL+"v2") MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req = NewRequest(t, "GET", setting.AppURL+"v2/token") MakeRequest(t, req, http.StatusUnauthorized) defer test.MockVariableValue(&setting.AppURL, "https://domain:8443/sub-path/")() @@ -129,12 +130,12 @@ func TestPackageContainer(t *testing.T) { t.Run("UserName/Password", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)) + req := NewRequest(t, "GET", setting.AppURL+"v2") resp := MakeRequest(t, req, http.StatusUnauthorized) assert.ElementsMatch(t, defaultAuthenticateValues, resp.Header().Values("WWW-Authenticate")) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)). + req = NewRequest(t, "GET", setting.AppURL+"v2/token"). AddBasicAuth(user.Name) resp = MakeRequest(t, req, http.StatusOK) @@ -147,9 +148,9 @@ func TestPackageContainer(t *testing.T) { assert.Equal(t, user.ID, pkgMeta.UserID) assert.Equal(t, auth_model.AccessTokenScopeAll, pkgMeta.Scope) - userToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) + userToken = "Bearer " + tokenResponse.Token - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + req = NewRequest(t, "GET", setting.AppURL+"v2"). AddTokenAuth(userToken) MakeRequest(t, req, http.StatusOK) }) @@ -161,23 +162,23 @@ func TestPackageContainer(t *testing.T) { session := loginUser(t, user.Name) readToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadPackage) - req := NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req := NewRequest(t, "GET", setting.AppURL+"v2/token") req.Request.SetBasicAuth(user.Name, readToken) resp := MakeRequest(t, req, http.StatusOK) tokenResponse := &TokenResponse{} DecodeJSON(t, resp, &tokenResponse) - readToken = fmt.Sprintf("Bearer %s", tokenResponse.Token) + readToken = "Bearer " + tokenResponse.Token badToken = getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeReadNotification) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req = NewRequest(t, "GET", setting.AppURL+"v2/token") req.Request.SetBasicAuth(user.Name, badToken) MakeRequest(t, req, http.StatusUnauthorized) testCase := func(scope auth_model.AccessTokenScope, expectedAuthStatus, expectedStatus int) { token := getTokenForLoggedInUser(t, session, scope) - req := NewRequest(t, "GET", fmt.Sprintf("%sv2/token", setting.AppURL)) + req := NewRequest(t, "GET", setting.AppURL+"v2/token") req.SetBasicAuth(user.Name, token) resp := MakeRequest(t, req, expectedAuthStatus) @@ -190,8 +191,8 @@ func TestPackageContainer(t *testing.T) { assert.NotEmpty(t, tokenResponse.Token) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). - AddTokenAuth(fmt.Sprintf("Bearer %s", tokenResponse.Token)) + req = NewRequest(t, "GET", setting.AppURL+"v2"). + AddTokenAuth("Bearer " + tokenResponse.Token) MakeRequest(t, req, expectedStatus) } testCase(auth_model.AccessTokenScopeReadPackage, http.StatusOK, http.StatusOK) @@ -204,17 +205,17 @@ func TestPackageContainer(t *testing.T) { t.Run("DetermineSupport", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + req := NewRequest(t, "GET", setting.AppURL+"v2"). AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "registry/2.0", resp.Header().Get("Docker-Distribution-Api-Version")) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + req = NewRequest(t, "GET", setting.AppURL+"v2"). AddTokenAuth(readToken) resp = MakeRequest(t, req, http.StatusOK) assert.Equal(t, "registry/2.0", resp.Header().Get("Docker-Distribution-Api-Version")) - req = NewRequest(t, "GET", fmt.Sprintf("%sv2", setting.AppURL)). + req = NewRequest(t, "GET", setting.AppURL+"v2"). AddTokenAuth(badToken) MakeRequest(t, req, http.StatusUnauthorized) }) @@ -226,15 +227,15 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadBlob/Monolithic", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req := NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(anonymousToken) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req = NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(readToken) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req = NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(badToken) MakeRequest(t, req, http.StatusUnauthorized) @@ -264,15 +265,15 @@ func TestPackageContainer(t *testing.T) { t.Run("UploadBlob/Chunked", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req := NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(readToken) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req = NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(badToken) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req = NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusAccepted) @@ -325,7 +326,7 @@ func TestPackageContainer(t *testing.T) { t.Run("Cancel", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "POST", fmt.Sprintf("%s/blobs/uploads", url)). + req := NewRequest(t, "POST", url+"/blobs/uploads"). AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusAccepted) @@ -441,7 +442,7 @@ func TestPackageContainer(t *testing.T) { assert.Equal(t, "application/vnd.docker.image.rootfs.diff.tar.gzip", pfd.Properties.GetByName(container_module.PropertyMediaType)) assert.Equal(t, blobDigest, pfd.Properties.GetByName(container_module.PropertyDigest)) default: - assert.FailNow(t, "unknown file: %s", pfd.File.Name) + assert.FailNow(t, "unknown file", "unknown file: %s", pfd.File.Name) } } @@ -467,7 +468,7 @@ func TestPackageContainer(t *testing.T) { t.Run("HeadManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "HEAD", fmt.Sprintf("%s/manifests/unknown-tag", url)). + req := NewRequest(t, "HEAD", url+"/manifests/unknown-tag"). AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) @@ -475,14 +476,14 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) - assert.Equal(t, fmt.Sprintf("%d", len(manifestContent)), resp.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(manifestContent)), resp.Header().Get("Content-Length")) assert.Equal(t, manifestDigest, resp.Header().Get("Docker-Content-Digest")) }) t.Run("GetManifest", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/manifests/unknown-tag", url)). + req := NewRequest(t, "GET", url+"/manifests/unknown-tag"). AddTokenAuth(userToken) MakeRequest(t, req, http.StatusNotFound) @@ -490,7 +491,7 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) - assert.Equal(t, fmt.Sprintf("%d", len(manifestContent)), resp.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(manifestContent)), resp.Header().Get("Content-Length")) assert.Equal(t, oci.MediaTypeImageManifest, resp.Header().Get("Content-Type")) assert.Equal(t, manifestDigest, resp.Header().Get("Docker-Content-Digest")) assert.Equal(t, manifestContent, resp.Body.String()) @@ -512,7 +513,7 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp = MakeRequest(t, req, http.StatusOK) - assert.Equal(t, fmt.Sprintf("%d", len(untaggedManifestContent)), resp.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(untaggedManifestContent)), resp.Header().Get("Content-Length")) assert.Equal(t, untaggedManifestDigest, resp.Header().Get("Docker-Content-Digest")) pv, err := packages_model.GetVersionByNameAndVersion(db.DefaultContext, user.ID, packages_model.TypeContainer, image, untaggedManifestDigest) @@ -598,7 +599,7 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) - assert.Equal(t, fmt.Sprintf("%d", len(blobContent)), resp.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(blobContent)), resp.Header().Get("Content-Length")) assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) req = NewRequest(t, "HEAD", fmt.Sprintf("%s/blobs/%s", url, blobDigest)). @@ -617,7 +618,7 @@ func TestPackageContainer(t *testing.T) { AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) - assert.Equal(t, fmt.Sprintf("%d", len(blobContent)), resp.Header().Get("Content-Length")) + assert.Equal(t, strconv.Itoa(len(blobContent)), resp.Header().Get("Content-Length")) assert.Equal(t, blobDigest, resp.Header().Get("Docker-Content-Digest")) assert.Equal(t, blobContent, resp.Body.Bytes()) }) @@ -631,27 +632,27 @@ func TestPackageContainer(t *testing.T) { ExpectedLink string }{ { - URL: fmt.Sprintf("%s/tags/list", url), + URL: url + "/tags/list", ExpectedTags: []string{"latest", "main", "multi"}, ExpectedLink: fmt.Sprintf(`; rel="next"`, user.Name, image), }, { - URL: fmt.Sprintf("%s/tags/list?n=0", url), + URL: url + "/tags/list?n=0", ExpectedTags: []string{}, ExpectedLink: "", }, { - URL: fmt.Sprintf("%s/tags/list?n=2", url), + URL: url + "/tags/list?n=2", ExpectedTags: []string{"latest", "main"}, ExpectedLink: fmt.Sprintf(`; rel="next"`, user.Name, image), }, { - URL: fmt.Sprintf("%s/tags/list?last=main", url), + URL: url + "/tags/list?last=main", ExpectedTags: []string{"multi"}, ExpectedLink: fmt.Sprintf(`; rel="next"`, user.Name, image), }, { - URL: fmt.Sprintf("%s/tags/list?n=1&last=latest", url), + URL: url + "/tags/list?n=1&last=latest", ExpectedTags: []string{"main"}, ExpectedLink: fmt.Sprintf(`; rel="next"`, user.Name, image), }, @@ -757,7 +758,7 @@ func TestPackageContainer(t *testing.T) { return func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%sv2/_catalog", setting.AppURL)). + req := NewRequest(t, "GET", setting.AppURL+"v2/_catalog"). AddTokenAuth(userToken) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_packages_cran_test.go b/tests/integration/api_packages_cran_test.go index 667ba0908c..bd4a99f331 100644 --- a/tests/integration/api_packages_cran_test.go +++ b/tests/integration/api_packages_cran_test.go @@ -133,8 +133,8 @@ func TestPackageCran(t *testing.T) { assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") body := resp.Body.String() - assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) - assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) + assert.Contains(t, body, "Package: "+packageName) + assert.Contains(t, body, "Version: "+packageVersion) req = NewRequest(t, "GET", url+"/src/contrib/PACKAGES.gz"). AddBasicAuth(user.Name) @@ -230,8 +230,8 @@ func TestPackageCran(t *testing.T) { assert.Contains(t, resp.Header().Get("Content-Type"), "text/plain") body := resp.Body.String() - assert.Contains(t, body, fmt.Sprintf("Package: %s", packageName)) - assert.Contains(t, body, fmt.Sprintf("Version: %s", packageVersion)) + assert.Contains(t, body, "Package: "+packageName) + assert.Contains(t, body, "Version: "+packageVersion) req = NewRequest(t, "GET", url+"/bin/windows/contrib/4.2/PACKAGES.gz"). AddBasicAuth(user.Name) diff --git a/tests/integration/api_packages_generic_test.go b/tests/integration/api_packages_generic_test.go index baa8dd66c8..5f410fc470 100644 --- a/tests/integration/api_packages_generic_test.go +++ b/tests/integration/api_packages_generic_test.go @@ -15,6 +15,7 @@ import ( "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/setting" + "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/tests" "github.com/stretchr/testify/assert" @@ -131,11 +132,7 @@ func TestPackageGeneric(t *testing.T) { t.Run("RequireSignInView", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - - setting.Service.RequireSignInView = true - defer func() { - setting.Service.RequireSignInView = false - }() + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() req = NewRequest(t, "GET", url+"/dummy.bin") MakeRequest(t, req, http.StatusUnauthorized) diff --git a/tests/integration/api_packages_helm_test.go b/tests/integration/api_packages_helm_test.go index 76285add11..8f5c6ac571 100644 --- a/tests/integration/api_packages_helm_test.go +++ b/tests/integration/api_packages_helm_test.go @@ -52,7 +52,7 @@ dependencies: zw := gzip.NewWriter(&buf) archive := tar.NewWriter(zw) archive.WriteHeader(&tar.Header{ - Name: fmt.Sprintf("%s/Chart.yaml", packageName), + Name: packageName + "/Chart.yaml", Mode: 0o600, Size: int64(len(chartContent)), }) @@ -122,7 +122,7 @@ dependencies: t.Run("Index", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/index.yaml", url)). + req := NewRequest(t, "GET", url+"/index.yaml"). AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_packages_npm_test.go b/tests/integration/api_packages_npm_test.go index ae1dd876f7..a190ed679d 100644 --- a/tests/integration/api_packages_npm_test.go +++ b/tests/integration/api_packages_npm_test.go @@ -28,7 +28,7 @@ func TestPackageNpm(t *testing.T) { user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - token := fmt.Sprintf("Bearer %s", getTokenForLoggedInUser(t, loginUser(t, user.Name), auth_model.AccessTokenScopeWritePackage)) + token := "Bearer " + getTokenForLoggedInUser(t, loginUser(t, user.Name), auth_model.AccessTokenScopeWritePackage) packageName := "@scope/test-package" packageVersion := "1.0.1-pre" diff --git a/tests/integration/api_packages_nuget_test.go b/tests/integration/api_packages_nuget_test.go index 622c2c4394..c0e69a82cd 100644 --- a/tests/integration/api_packages_nuget_test.go +++ b/tests/integration/api_packages_nuget_test.go @@ -198,7 +198,7 @@ func TestPackageNuGet(t *testing.T) { t.Run(c.Owner, func(t *testing.T) { url := fmt.Sprintf("/api/packages/%s/nuget", c.Owner) - req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url)) + req := NewRequest(t, "GET", url+"/index.json") if c.UseBasicAuth { req.AddBasicAuth(user.Name) } else if c.token != "" { @@ -273,10 +273,10 @@ func TestPackageNuGet(t *testing.T) { pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - case fmt.Sprintf("%s.nuspec", packageName): + case packageName + ".nuspec": assert.False(t, pf.IsLead) default: - assert.Fail(t, "unexpected filename: %v", pf.Name) + assert.Fail(t, "unexpected filename", "unexpected filename: %v", pf.Name) } } @@ -319,10 +319,10 @@ func TestPackageNuGet(t *testing.T) { pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) assert.NoError(t, err) assert.Equal(t, int64(len(content)), pb.Size) - case fmt.Sprintf("%s.nuspec", packageName): + case packageName + ".nuspec": assert.False(t, pf.IsLead) default: - assert.Fail(t, "unexpected filename: %v", pf.Name) + assert.Fail(t, "unexpected filename", "unexpected filename: %v", pf.Name) } } @@ -360,15 +360,15 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) return &buf } - req := NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage("unknown-package", "SymbolsPackage")). + req := NewRequestWithBody(t, "PUT", url+"/symbolpackage", createSymbolPackage("unknown-package", "SymbolsPackage")). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusNotFound) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "DummyPackage")). + req = NewRequestWithBody(t, "PUT", url+"/symbolpackage", createSymbolPackage(packageName, "DummyPackage")). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")). + req = NewRequestWithBody(t, "PUT", url+"/symbolpackage", createSymbolPackage(packageName, "SymbolsPackage")). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusCreated) @@ -400,7 +400,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) assert.NoError(t, err) assert.Equal(t, int64(616), pb.Size) - case fmt.Sprintf("%s.nuspec", packageName): + case packageName + ".nuspec": assert.False(t, pf.IsLead) pb, err := packages.GetBlobByID(db.DefaultContext, pf.BlobID) @@ -419,11 +419,11 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) assert.Equal(t, nuget_module.PropertySymbolID, pps[0].Name) assert.Equal(t, symbolID, pps[0].Value) default: - assert.FailNow(t, "unexpected file: %v", pf.Name) + assert.FailNow(t, "unexpected file", "unexpected file: %v", pf.Name) } } - req = NewRequestWithBody(t, "PUT", fmt.Sprintf("%s/symbolpackage", url), createSymbolPackage(packageName, "SymbolsPackage")). + req = NewRequestWithBody(t, "PUT", url+"/symbolpackage", createSymbolPackage(packageName, "SymbolsPackage")). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusConflict) }) @@ -631,7 +631,7 @@ AAAjQmxvYgAAAGm7ENm9SGxMtAFVvPUsPJTF6PbtAAAAAFcVogEJAAAAAQAAAA==`) }) t.Run("Next", func(t *testing.T) { - req := NewRequest(t, "GET", fmt.Sprintf("%s/Search()?searchTerm='test'&$skip=0&$top=1", url)). + req := NewRequest(t, "GET", url+"/Search()?searchTerm='test'&$skip=0&$top=1"). AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/api_packages_pub_test.go b/tests/integration/api_packages_pub_test.go index 11da894ddf..3c1bca908e 100644 --- a/tests/integration/api_packages_pub_test.go +++ b/tests/integration/api_packages_pub_test.go @@ -37,7 +37,7 @@ func TestPackagePub(t *testing.T) { packageVersion := "1.0.1" packageDescription := "Test Description" - filename := fmt.Sprintf("%s.tar.gz", packageVersion) + filename := packageVersion + ".tar.gz" pubspecContent := `name: ` + packageName + ` version: ` + packageVersion + ` diff --git a/tests/integration/api_packages_pypi_test.go b/tests/integration/api_packages_pypi_test.go index 2dabb5005b..54db45f1ac 100644 --- a/tests/integration/api_packages_pypi_test.go +++ b/tests/integration/api_packages_pypi_test.go @@ -67,7 +67,7 @@ func TestPackagePyPI(t *testing.T) { body, writer, closeFunc := createBasicMultipartFile(filename, packageName, content) writer.WriteField("project_urls", "DOCUMENTATION , https://readthedocs.org") - writer.WriteField("project_urls", fmt.Sprintf("Home-page, %s", projectURL)) + writer.WriteField("project_urls", "Home-page, "+projectURL) _ = closeFunc() diff --git a/tests/integration/api_packages_rpm_test.go b/tests/integration/api_packages_rpm_test.go index 6feceaeb78..469bd1fc6c 100644 --- a/tests/integration/api_packages_rpm_test.go +++ b/tests/integration/api_packages_rpm_test.go @@ -317,7 +317,7 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, var result Metadata decodeGzipXML(t, resp, &result) - assert.EqualValues(t, 1, result.PackageCount) + assert.Equal(t, 1, result.PackageCount) assert.Len(t, result.Packages, 1) p := result.Packages[0] assert.Equal(t, "rpm", p.Type) @@ -366,7 +366,7 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, var result Filelists decodeGzipXML(t, resp, &result) - assert.EqualValues(t, 1, result.PackageCount) + assert.Equal(t, 1, result.PackageCount) assert.Len(t, result.Packages, 1) p := result.Packages[0] assert.NotEmpty(t, p.Pkgid) @@ -403,7 +403,7 @@ gpgkey=%sapi/packages/%s/rpm/repository.key`, var result Other decodeGzipXML(t, resp, &result) - assert.EqualValues(t, 1, result.PackageCount) + assert.Equal(t, 1, result.PackageCount) assert.Len(t, result.Packages, 1) p := result.Packages[0] assert.NotEmpty(t, p.Pkgid) diff --git a/tests/integration/api_packages_rubygems_test.go b/tests/integration/api_packages_rubygems_test.go index fe9283df4d..ab76c52440 100644 --- a/tests/integration/api_packages_rubygems_test.go +++ b/tests/integration/api_packages_rubygems_test.go @@ -185,7 +185,7 @@ func TestPackageRubyGems(t *testing.T) { root := fmt.Sprintf("/api/packages/%s/rubygems", user.Name) uploadFile := func(t *testing.T, content []byte, expectedStatus int) { - req := NewRequestWithBody(t, "POST", fmt.Sprintf("%s/api/v1/gems", root), bytes.NewReader(content)). + req := NewRequestWithBody(t, "POST", root+"/api/v1/gems", bytes.NewReader(content)). AddBasicAuth(user.Name) MakeRequest(t, req, expectedStatus) } @@ -293,7 +293,7 @@ gAAAAP//MS06Gw==`) t.Run("Versions", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/versions", root)).AddBasicAuth(user.Name) + req := NewRequest(t, "GET", root+"/versions").AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, `--- gitea 1.0.5 08843c2dd0ea19910e6b056b98e38f1c @@ -307,7 +307,7 @@ gitea-another 0.99 8b639e4048d282941485368ec42609be _ = writer.WriteField("gem_name", packageName) _ = writer.WriteField("version", packageVersion) _ = writer.Close() - req := NewRequestWithBody(t, "DELETE", fmt.Sprintf("%s/api/v1/gems/yank", root), &body). + req := NewRequestWithBody(t, "DELETE", root+"/api/v1/gems/yank", &body). SetHeader("Content-Type", writer.FormDataContentType()). AddBasicAuth(user.Name) MakeRequest(t, req, http.StatusOK) @@ -330,7 +330,7 @@ gitea-another 0.99 8b639e4048d282941485368ec42609be t.Run("VersionsAfterDelete", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("%s/versions", root)).AddBasicAuth(user.Name) + req := NewRequest(t, "GET", root+"/versions").AddBasicAuth(user.Name) resp := MakeRequest(t, req, http.StatusOK) assert.Equal(t, "---\n", resp.Body.String()) }) diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index 978a690302..8a9565f087 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -49,7 +49,7 @@ func TestPackageAPI(t *testing.T) { t.Run("ListPackages", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s", user.Name)). + req := NewRequest(t, "GET", "/api/v1/packages/"+user.Name). AddTokenAuth(tokenReadPackage) resp := MakeRequest(t, req, http.StatusOK) @@ -116,7 +116,7 @@ func TestPackageAPI(t *testing.T) { var ap2 *api.Package DecodeJSON(t, resp, &ap2) assert.NotNil(t, ap2.Repository) - assert.EqualValues(t, newRepo.ID, ap2.Repository.ID) + assert.Equal(t, newRepo.ID, ap2.Repository.ID) // link to repository without write access, should fail req = NewRequest(t, "POST", fmt.Sprintf("/api/v1/packages/%s/generic/%s/-/link/%s", user.Name, packageName, "repo3")).AddTokenAuth(tokenWritePackage) @@ -408,7 +408,7 @@ func TestPackageAccess(t *testing.T) { {limitedOrgNoMember, http.StatusOK}, {publicOrgNoMember, http.StatusOK}, } { - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/packages/%s", target.Owner.Name)). + req := NewRequest(t, "GET", "/api/v1/packages/"+target.Owner.Name). AddTokenAuth(tokenReadPackage) MakeRequest(t, req, target.ExpectedStatus) } diff --git a/tests/integration/api_packages_vagrant_test.go b/tests/integration/api_packages_vagrant_test.go index a5e954f3a2..1743e37222 100644 --- a/tests/integration/api_packages_vagrant_test.go +++ b/tests/integration/api_packages_vagrant_test.go @@ -35,7 +35,7 @@ func TestPackageVagrant(t *testing.T) { packageDescription := "Test Description" packageProvider := "virtualbox" - filename := fmt.Sprintf("%s.box", packageProvider) + filename := packageProvider + ".box" infoContent, _ := json.Marshal(map[string]string{ "description": packageDescription, @@ -59,7 +59,7 @@ func TestPackageVagrant(t *testing.T) { t.Run("Authenticate", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - authenticateURL := fmt.Sprintf("%s/authenticate", root) + authenticateURL := root + "/authenticate" req := NewRequest(t, "GET", authenticateURL) MakeRequest(t, req, http.StatusUnauthorized) diff --git a/tests/integration/api_pull_review_test.go b/tests/integration/api_pull_review_test.go index b85882a510..1fc65ddea8 100644 --- a/tests/integration/api_pull_review_test.go +++ b/tests/integration/api_pull_review_test.go @@ -43,17 +43,17 @@ func TestAPIPullReview(t *testing.T) { require.Len(t, reviews, 8) for _, r := range reviews { - assert.EqualValues(t, pullIssue.HTMLURL(), r.HTMLPullURL) + assert.Equal(t, pullIssue.HTMLURL(), r.HTMLPullURL) } assert.EqualValues(t, 8, reviews[3].ID) assert.EqualValues(t, "APPROVED", reviews[3].State) - assert.EqualValues(t, 0, reviews[3].CodeCommentsCount) + assert.Equal(t, 0, reviews[3].CodeCommentsCount) assert.True(t, reviews[3].Stale) assert.False(t, reviews[3].Official) assert.EqualValues(t, 10, reviews[5].ID) assert.EqualValues(t, "REQUEST_CHANGES", reviews[5].State) - assert.EqualValues(t, 1, reviews[5].CodeCommentsCount) + assert.Equal(t, 1, reviews[5].CodeCommentsCount) assert.EqualValues(t, -1, reviews[5].Reviewer.ID) // ghost user assert.False(t, reviews[5].Stale) assert.True(t, reviews[5].Official) @@ -64,13 +64,13 @@ func TestAPIPullReview(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) var review api.PullReview DecodeJSON(t, resp, &review) - assert.EqualValues(t, *reviews[3], review) + assert.Equal(t, *reviews[3], review) req = NewRequestf(t, "GET", "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, reviews[5].ID). AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) - assert.EqualValues(t, *reviews[5], review) + assert.Equal(t, *reviews[5], review) // test GetPullReviewComments comment := unittest.AssertExistsAndLoadBean(t, &issues_model.Comment{ID: 7}) @@ -80,11 +80,11 @@ func TestAPIPullReview(t *testing.T) { var reviewComments []*api.PullReviewComment DecodeJSON(t, resp, &reviewComments) assert.Len(t, reviewComments, 1) - assert.EqualValues(t, "Ghost", reviewComments[0].Poster.UserName) - assert.EqualValues(t, "a review from a deleted user", reviewComments[0].Body) - assert.EqualValues(t, comment.ID, reviewComments[0].ID) + assert.Equal(t, "Ghost", reviewComments[0].Poster.UserName) + assert.Equal(t, "a review from a deleted user", reviewComments[0].Body) + assert.Equal(t, comment.ID, reviewComments[0].ID) assert.EqualValues(t, comment.UpdatedUnix, reviewComments[0].Updated.Unix()) - assert.EqualValues(t, comment.HTMLURL(db.DefaultContext), reviewComments[0].HTMLURL) + assert.Equal(t, comment.HTMLURL(db.DefaultContext), reviewComments[0].HTMLURL) // test CreatePullReview req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews", repo.OwnerName, repo.Name, pullIssue.Index), &api.CreatePullReviewOptions{ @@ -113,7 +113,7 @@ func TestAPIPullReview(t *testing.T) { DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) assert.EqualValues(t, "PENDING", review.State) - assert.EqualValues(t, 3, review.CodeCommentsCount) + assert.Equal(t, 3, review.CodeCommentsCount) // test SubmitPullReview req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.SubmitPullReviewOptions{ @@ -124,7 +124,7 @@ func TestAPIPullReview(t *testing.T) { DecodeJSON(t, resp, &review) assert.EqualValues(t, 6, review.ID) assert.EqualValues(t, "APPROVED", review.State) - assert.EqualValues(t, 3, review.CodeCommentsCount) + assert.Equal(t, 3, review.CodeCommentsCount) // test dismiss review req = NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls/%d/reviews/%d/dismissals", repo.OwnerName, repo.Name, pullIssue.Index, review.ID), &api.DismissPullReviewOptions{ @@ -151,7 +151,7 @@ func TestAPIPullReview(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &review) assert.EqualValues(t, "COMMENT", review.State) - assert.EqualValues(t, 0, review.CodeCommentsCount) + assert.Equal(t, 0, review.CodeCommentsCount) req = NewRequestf(t, http.MethodDelete, "/api/v1/repos/%s/%s/pulls/%d/reviews/%d", repo.OwnerName, repo.Name, pullIssue.Index, review.ID). AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) @@ -179,7 +179,7 @@ func TestAPIPullReview(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &commentReview) assert.EqualValues(t, "COMMENT", commentReview.State) - assert.EqualValues(t, 2, commentReview.CodeCommentsCount) + assert.Equal(t, 2, commentReview.CodeCommentsCount) assert.Empty(t, commentReview.Body) assert.False(t, commentReview.Dismissed) @@ -194,8 +194,8 @@ func TestAPIPullReview(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &commentReview) assert.EqualValues(t, "COMMENT", commentReview.State) - assert.EqualValues(t, 0, commentReview.CodeCommentsCount) - assert.EqualValues(t, commentBody, commentReview.Body) + assert.Equal(t, 0, commentReview.CodeCommentsCount) + assert.Equal(t, commentBody, commentReview.Body) assert.False(t, commentReview.Dismissed) // test CreatePullReview Comment without body and no comments @@ -207,7 +207,7 @@ func TestAPIPullReview(t *testing.T) { resp = MakeRequest(t, req, http.StatusUnprocessableEntity) errMap := make(map[string]any) json.Unmarshal(resp.Body.Bytes(), &errMap) - assert.EqualValues(t, "review event COMMENT requires a body or a comment", errMap["message"].(string)) + assert.Equal(t, "review event COMMENT requires a body or a comment", errMap["message"].(string)) // test get review requests // to make it simple, use same api with get review @@ -221,14 +221,14 @@ func TestAPIPullReview(t *testing.T) { DecodeJSON(t, resp, &reviews) assert.EqualValues(t, 11, reviews[0].ID) assert.EqualValues(t, "REQUEST_REVIEW", reviews[0].State) - assert.EqualValues(t, 0, reviews[0].CodeCommentsCount) + assert.Equal(t, 0, reviews[0].CodeCommentsCount) assert.False(t, reviews[0].Stale) assert.True(t, reviews[0].Official) - assert.EqualValues(t, "test_team", reviews[0].ReviewerTeam.Name) + assert.Equal(t, "test_team", reviews[0].ReviewerTeam.Name) assert.EqualValues(t, 12, reviews[1].ID) assert.EqualValues(t, "REQUEST_REVIEW", reviews[1].State) - assert.EqualValues(t, 0, reviews[0].CodeCommentsCount) + assert.Equal(t, 0, reviews[0].CodeCommentsCount) assert.False(t, reviews[1].Stale) assert.True(t, reviews[1].Official) assert.EqualValues(t, 1, reviews[1].Reviewer.ID) diff --git a/tests/integration/api_pull_test.go b/tests/integration/api_pull_test.go index 39c6c34a30..f3165c6fc5 100644 --- a/tests/integration/api_pull_test.go +++ b/tests/integration/api_pull_test.go @@ -61,8 +61,8 @@ func TestAPIViewPulls(t *testing.T) { assert.Equal(t, "File-WoW", patch.Files[0].Name) // FIXME: The old name should be empty if it's a file add type assert.Equal(t, "File-WoW", patch.Files[0].OldName) - assert.EqualValues(t, 1, patch.Files[0].Addition) - assert.EqualValues(t, 0, patch.Files[0].Deletion) + assert.Equal(t, 1, patch.Files[0].Addition) + assert.Equal(t, 0, patch.Files[0].Deletion) assert.Equal(t, gitdiff.DiffFileAdd, patch.Files[0].Type) } @@ -71,9 +71,9 @@ func TestAPIViewPulls(t *testing.T) { if assert.Len(t, files, 1) { assert.Equal(t, "File-WoW", files[0].Filename) assert.Empty(t, files[0].PreviousFilename) - assert.EqualValues(t, 1, files[0].Additions) - assert.EqualValues(t, 1, files[0].Changes) - assert.EqualValues(t, 0, files[0].Deletions) + assert.Equal(t, 1, files[0].Additions) + assert.Equal(t, 1, files[0].Changes) + assert.Equal(t, 0, files[0].Deletions) assert.Equal(t, "added", files[0].Status) } })) @@ -97,8 +97,8 @@ func TestAPIViewPulls(t *testing.T) { if assert.Len(t, patch.Files, 1) { assert.Equal(t, "README.md", patch.Files[0].Name) assert.Equal(t, "README.md", patch.Files[0].OldName) - assert.EqualValues(t, 4, patch.Files[0].Addition) - assert.EqualValues(t, 1, patch.Files[0].Deletion) + assert.Equal(t, 4, patch.Files[0].Addition) + assert.Equal(t, 1, patch.Files[0].Deletion) assert.Equal(t, gitdiff.DiffFileChange, patch.Files[0].Type) } @@ -107,9 +107,9 @@ func TestAPIViewPulls(t *testing.T) { if assert.Len(t, files, 1) { assert.Equal(t, "README.md", files[0].Filename) // FIXME: The PreviousFilename name should be the same as Filename if it's a file change - assert.Equal(t, "", files[0].PreviousFilename) - assert.EqualValues(t, 4, files[0].Additions) - assert.EqualValues(t, 1, files[0].Deletions) + assert.Empty(t, files[0].PreviousFilename) + assert.Equal(t, 4, files[0].Additions) + assert.Equal(t, 1, files[0].Deletions) assert.Equal(t, "changed", files[0].Status) } })) @@ -193,7 +193,7 @@ func TestAPICreatePullSuccess(t *testing.T) { session := loginUser(t, owner11.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner10.Name, repo10.Name), &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:master", owner11.Name), + Head: owner11.Name + ":master", Base: "master", Title: "create a failure pr", }).AddTokenAuth(token) @@ -213,7 +213,7 @@ func TestAPICreatePullBasePermission(t *testing.T) { session := loginUser(t, user4.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:master", repo11.OwnerName), + Head: repo11.OwnerName + ":master", Base: "master", Title: "create a failure pr", } @@ -241,7 +241,7 @@ func TestAPICreatePullHeadPermission(t *testing.T) { session := loginUser(t, user4.Name) token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:master", repo11.OwnerName), + Head: repo11.OwnerName + ":master", Base: "master", Title: "create a failure pr", } @@ -269,7 +269,7 @@ func TestAPICreatePullSameRepoSuccess(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) req := NewRequestWithJSON(t, http.MethodPost, fmt.Sprintf("/api/v1/repos/%s/%s/pulls", owner.Name, repo.Name), &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:pr-to-update", owner.Name), + Head: owner.Name + ":pr-to-update", Base: "master", Title: "successfully create a PR between branches of the same repository", }).AddTokenAuth(token) @@ -290,7 +290,7 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:master", owner11.Name), + Head: owner11.Name + ":master", Base: "master", Title: "create a failure pr", Body: "foobaaar", @@ -307,12 +307,12 @@ func TestAPICreatePullWithFieldsSuccess(t *testing.T) { DecodeJSON(t, res, pull) assert.NotNil(t, pull.Milestone) - assert.EqualValues(t, opts.Milestone, pull.Milestone.ID) + assert.Equal(t, opts.Milestone, pull.Milestone.ID) if assert.Len(t, pull.Assignees, 1) { - assert.EqualValues(t, opts.Assignees[0], owner10.Name) + assert.Equal(t, opts.Assignees[0], owner10.Name) } assert.NotNil(t, pull.Labels) - assert.EqualValues(t, opts.Labels[0], pull.Labels[0].ID) + assert.Equal(t, opts.Labels[0], pull.Labels[0].ID) } func TestAPICreatePullWithFieldsFailure(t *testing.T) { @@ -328,7 +328,7 @@ func TestAPICreatePullWithFieldsFailure(t *testing.T) { token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) opts := &api.CreatePullRequestOption{ - Head: fmt.Sprintf("%s:master", owner11.Name), + Head: owner11.Name + ":master", Base: "master", } @@ -366,7 +366,7 @@ func TestAPIEditPull(t *testing.T) { apiPull := new(api.PullRequest) resp := MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, apiPull) - assert.EqualValues(t, "master", apiPull.Base.Name) + assert.Equal(t, "master", apiPull.Base.Name) newTitle := "edit a this pr" newBody := "edited body" @@ -377,7 +377,7 @@ func TestAPIEditPull(t *testing.T) { }).AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, apiPull) - assert.EqualValues(t, "feature/1", apiPull.Base.Name) + assert.Equal(t, "feature/1", apiPull.Base.Name) // check comment history pull := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: apiPull.ID}) err := pull.LoadIssue(db.DefaultContext) diff --git a/tests/integration/api_releases_test.go b/tests/integration/api_releases_test.go index b3d4928b7b..a3dbc0363b 100644 --- a/tests/integration/api_releases_test.go +++ b/tests/integration/api_releases_test.go @@ -97,7 +97,7 @@ func createNewReleaseUsingAPI(t *testing.T, token string, owner *user_model.User Title: newRelease.Title, } unittest.AssertExistsAndLoadBean(t, rel) - assert.EqualValues(t, newRelease.Note, rel.Note) + assert.Equal(t, newRelease.Note, rel.Note) return &newRelease } @@ -151,7 +151,7 @@ func TestAPICreateAndUpdateRelease(t *testing.T) { Title: newRelease.Title, } unittest.AssertExistsAndLoadBean(t, rel) - assert.EqualValues(t, rel.Note, newRelease.Note) + assert.Equal(t, rel.Note, newRelease.Note) } func TestAPICreateProtectedTagRelease(t *testing.T) { @@ -329,7 +329,7 @@ func TestAPIUploadAssetRelease(t *testing.T) { var attachment *api.Attachment DecodeJSON(t, resp, &attachment) - assert.EqualValues(t, filename, attachment.Name) + assert.Equal(t, filename, attachment.Name) assert.EqualValues(t, 104, attachment.Size) req = NewRequestWithBody(t, http.MethodPost, assetURL+"?name=test-asset", bytes.NewReader(body.Bytes())). @@ -340,7 +340,7 @@ func TestAPIUploadAssetRelease(t *testing.T) { var attachment2 *api.Attachment DecodeJSON(t, resp, &attachment2) - assert.EqualValues(t, "test-asset", attachment2.Name) + assert.Equal(t, "test-asset", attachment2.Name) assert.EqualValues(t, 104, attachment2.Size) }) @@ -358,7 +358,7 @@ func TestAPIUploadAssetRelease(t *testing.T) { var attachment *api.Attachment DecodeJSON(t, resp, &attachment) - assert.EqualValues(t, "stream.bin", attachment.Name) + assert.Equal(t, "stream.bin", attachment.Name) assert.EqualValues(t, 104, attachment.Size) }) } diff --git a/tests/integration/api_repo_archive_test.go b/tests/integration/api_repo_archive_test.go index 8589199da3..e698148d84 100644 --- a/tests/integration/api_repo_archive_test.go +++ b/tests/integration/api_repo_archive_test.go @@ -48,7 +48,7 @@ func TestAPIDownloadArchive(t *testing.T) { bs2, err := io.ReadAll(resp.Body) assert.NoError(t, err) // The locked URL should give the same bytes as the non-locked one - assert.EqualValues(t, bs, bs2) + assert.Equal(t, bs, bs2) link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/archive/master.bundle", user2.Name, repo.Name)) resp = MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK) @@ -88,7 +88,7 @@ func TestAPIDownloadArchive2(t *testing.T) { bs2, err := io.ReadAll(resp.Body) assert.NoError(t, err) // The locked URL should give the same bytes as the non-locked one - assert.EqualValues(t, bs, bs2) + assert.Equal(t, bs, bs2) link, _ = url.Parse(fmt.Sprintf("/api/v1/repos/%s/%s/bundle/master", user2.Name, repo.Name)) resp = MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK) diff --git a/tests/integration/api_repo_branch_test.go b/tests/integration/api_repo_branch_test.go index 63080b308c..066eb366b1 100644 --- a/tests/integration/api_repo_branch_test.go +++ b/tests/integration/api_repo_branch_test.go @@ -4,11 +4,11 @@ package integration import ( - "bytes" "fmt" "io" "net/http" "net/url" + "strings" "testing" auth_model "code.gitea.io/gitea/models/auth" @@ -42,8 +42,8 @@ func TestAPIRepoBranchesPlain(t *testing.T) { var branches []*api.Branch assert.NoError(t, json.Unmarshal(bs, &branches)) assert.Len(t, branches, 2) - assert.EqualValues(t, "test_branch", branches[0].Name) - assert.EqualValues(t, "master", branches[1].Name) + assert.Equal(t, "test_branch", branches[0].Name) + assert.Equal(t, "master", branches[1].Name) link2, _ := url.Parse(fmt.Sprintf("/api/v1/repos/org3/%s/branches/test_branch", repo3.Name)) MakeRequest(t, NewRequest(t, "GET", link2.String()).AddTokenAuth(publicOnlyToken), http.StatusForbidden) @@ -53,20 +53,20 @@ func TestAPIRepoBranchesPlain(t *testing.T) { assert.NoError(t, err) var branch api.Branch assert.NoError(t, json.Unmarshal(bs, &branch)) - assert.EqualValues(t, "test_branch", branch.Name) + assert.Equal(t, "test_branch", branch.Name) MakeRequest(t, NewRequest(t, "POST", link.String()).AddTokenAuth(publicOnlyToken), http.StatusForbidden) req := NewRequest(t, "POST", link.String()).AddTokenAuth(token) req.Header.Add("Content-Type", "application/json") - req.Body = io.NopCloser(bytes.NewBufferString(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`)) + req.Body = io.NopCloser(strings.NewReader(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`)) resp = MakeRequest(t, req, http.StatusCreated) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) var branch2 api.Branch assert.NoError(t, json.Unmarshal(bs, &branch2)) - assert.EqualValues(t, "test_branch2", branch2.Name) - assert.EqualValues(t, branch.Commit.ID, branch2.Commit.ID) + assert.Equal(t, "test_branch2", branch2.Name) + assert.Equal(t, branch.Commit.ID, branch2.Commit.ID) resp = MakeRequest(t, NewRequest(t, "GET", link.String()).AddTokenAuth(token), http.StatusOK) bs, err = io.ReadAll(resp.Body) @@ -75,9 +75,9 @@ func TestAPIRepoBranchesPlain(t *testing.T) { branches = []*api.Branch{} assert.NoError(t, json.Unmarshal(bs, &branches)) assert.Len(t, branches, 3) - assert.EqualValues(t, "test_branch", branches[0].Name) - assert.EqualValues(t, "test_branch2", branches[1].Name) - assert.EqualValues(t, "master", branches[2].Name) + assert.Equal(t, "test_branch", branches[0].Name) + assert.Equal(t, "test_branch2", branches[1].Name) + assert.Equal(t, "master", branches[2].Name) link3, _ := url.Parse(fmt.Sprintf("/api/v1/repos/org3/%s/branches/test_branch2", repo3.Name)) MakeRequest(t, NewRequest(t, "DELETE", link3.String()), http.StatusNotFound) @@ -104,8 +104,8 @@ func TestAPIRepoBranchesMirror(t *testing.T) { var branches []*api.Branch assert.NoError(t, json.Unmarshal(bs, &branches)) assert.Len(t, branches, 2) - assert.EqualValues(t, "test_branch", branches[0].Name) - assert.EqualValues(t, "master", branches[1].Name) + assert.Equal(t, "test_branch", branches[0].Name) + assert.Equal(t, "master", branches[1].Name) link2, _ := url.Parse(fmt.Sprintf("/api/v1/repos/org3/%s/branches/test_branch", repo5.Name)) resp = MakeRequest(t, NewRequest(t, "GET", link2.String()).AddTokenAuth(token), http.StatusOK) @@ -113,18 +113,18 @@ func TestAPIRepoBranchesMirror(t *testing.T) { assert.NoError(t, err) var branch api.Branch assert.NoError(t, json.Unmarshal(bs, &branch)) - assert.EqualValues(t, "test_branch", branch.Name) + assert.Equal(t, "test_branch", branch.Name) req := NewRequest(t, "POST", link.String()).AddTokenAuth(token) req.Header.Add("Content-Type", "application/json") - req.Body = io.NopCloser(bytes.NewBufferString(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`)) + req.Body = io.NopCloser(strings.NewReader(`{"new_branch_name":"test_branch2", "old_branch_name": "test_branch", "old_ref_name":"refs/heads/test_branch"}`)) resp = MakeRequest(t, req, http.StatusForbidden) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"api/swagger\"}\n", string(bs)) + assert.Equal(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"api/swagger\"}\n", string(bs)) resp = MakeRequest(t, NewRequest(t, "DELETE", link2.String()).AddTokenAuth(token), http.StatusForbidden) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"api/swagger\"}\n", string(bs)) + assert.Equal(t, "{\"message\":\"Git Repository is a mirror.\",\"url\":\""+setting.AppURL+"api/swagger\"}\n", string(bs)) } diff --git a/tests/integration/api_repo_file_create_test.go b/tests/integration/api_repo_file_create_test.go index 2bf4a81280..0a7f37facb 100644 --- a/tests/integration/api_repo_file_create_test.go +++ b/tests/integration/api_repo_file_create_test.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" "net/url" - "path/filepath" + "path" "testing" "time" @@ -49,28 +49,42 @@ func getCreateFileOptions() api.CreateFileOptions { } } -func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCommitSHA string) *api.FileResponse { +func normalizeFileContentResponseCommitTime(c *api.ContentsResponse) { + // decoded JSON response may contain different timezone from the one parsed by git commit + // so we need to normalize the time to UTC to make "assert.Equal" pass + c.LastCommitterDate = c.LastCommitterDate.UTC() + c.LastAuthorDate = c.LastAuthorDate.UTC() +} + +type apiFileResponseInfo struct { + repoFullName, commitID, treePath, lastCommitSHA string + lastCommitterWhen, lastAuthorWhen time.Time +} + +func getExpectedFileResponseForCreate(info apiFileResponseInfo) *api.FileResponse { sha := "a635aa942442ddfdba07468cf9661c08fbdf0ebf" encoding := "base64" content := "VGhpcyBpcyBuZXcgdGV4dA==" - selfURL := setting.AppURL + "api/v1/repos/" + repoFullName + "/contents/" + treePath + "?ref=master" - htmlURL := setting.AppURL + repoFullName + "/src/branch/master/" + treePath - gitURL := setting.AppURL + "api/v1/repos/" + repoFullName + "/git/blobs/" + sha - downloadURL := setting.AppURL + repoFullName + "/raw/branch/master/" + treePath - return &api.FileResponse{ + selfURL := setting.AppURL + "api/v1/repos/" + info.repoFullName + "/contents/" + info.treePath + "?ref=master" + htmlURL := setting.AppURL + info.repoFullName + "/src/branch/master/" + info.treePath + gitURL := setting.AppURL + "api/v1/repos/" + info.repoFullName + "/git/blobs/" + sha + downloadURL := setting.AppURL + info.repoFullName + "/raw/branch/master/" + info.treePath + ret := &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - LastCommitSHA: latestCommitSHA, - Size: 16, - Type: "file", - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: path.Base(info.treePath), + Path: info.treePath, + SHA: sha, + LastCommitSHA: info.lastCommitSHA, + LastCommitterDate: info.lastCommitterWhen, + LastAuthorDate: info.lastAuthorWhen, + Size: 16, + Type: "file", + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -79,10 +93,10 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCo }, Commit: &api.FileCommitResponse{ CommitMeta: api.CommitMeta{ - URL: setting.AppURL + "api/v1/repos/" + repoFullName + "/git/commits/" + commitID, - SHA: commitID, + URL: setting.AppURL + "api/v1/repos/" + info.repoFullName + "/git/commits/" + info.commitID, + SHA: info.commitID, }, - HTMLURL: setting.AppURL + repoFullName + "/commit/" + commitID, + HTMLURL: setting.AppURL + info.repoFullName + "/commit/" + info.commitID, Author: &api.CommitUser{ Identity: api.Identity{ Name: "Anne Doe", @@ -106,6 +120,8 @@ func getExpectedFileResponseForCreate(repoFullName, commitID, treePath, latestCo Payload: "", }, } + normalizeFileContentResponseCommitTime(ret.Content) + return ret } func BenchmarkAPICreateFileSmall(b *testing.B) { @@ -167,21 +183,29 @@ func TestAPICreateFile(t *testing.T) { AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusCreated) gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo1) + defer gitRepo.Close() commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) - latestCommit, _ := gitRepo.GetCommitByPath(treePath) - expectedFileResponse := getExpectedFileResponseForCreate("user2/repo1", commitID, treePath, latestCommit.ID.String()) + lastCommit, _ := gitRepo.GetCommitByPath(treePath) + expectedFileResponse := getExpectedFileResponseForCreate(apiFileResponseInfo{ + repoFullName: "user2/repo1", + commitID: commitID, + treePath: treePath, + lastCommitSHA: lastCommit.ID.String(), + lastCommitterWhen: lastCommit.Committer.When, + lastAuthorWhen: lastCommit.Author.When, + }) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) - assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Date, fileResponse.Commit.Author.Date) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Email, fileResponse.Commit.Committer.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Name, fileResponse.Commit.Committer.Name) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Date, fileResponse.Commit.Committer.Date) - gitRepo.Close() + normalizeFileContentResponseCommitTime(fileResponse.Content) + assert.Equal(t, expectedFileResponse.Content, fileResponse.Content) + assert.Equal(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) + assert.Equal(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) + assert.Equal(t, expectedFileResponse.Commit.Author.Date, fileResponse.Commit.Author.Date) + assert.Equal(t, expectedFileResponse.Commit.Committer.Email, fileResponse.Commit.Committer.Email) + assert.Equal(t, expectedFileResponse.Commit.Committer.Name, fileResponse.Commit.Committer.Name) + assert.Equal(t, expectedFileResponse.Commit.Committer.Date, fileResponse.Commit.Committer.Date) } // Test creating a file in a new branch @@ -198,10 +222,10 @@ func TestAPICreateFile(t *testing.T) { expectedSHA := "a635aa942442ddfdba07468cf9661c08fbdf0ebf" expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/new_branch/new/file%d.txt", fileID) expectedDownloadURL := fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/new_branch/new/file%d.txt", fileID) - assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA) - assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) - assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) - assert.EqualValues(t, createFileOptions.Message+"\n", fileResponse.Commit.Message) + assert.Equal(t, expectedSHA, fileResponse.Content.SHA) + assert.Equal(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) + assert.Equal(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) + assert.Equal(t, createFileOptions.Message+"\n", fileResponse.Commit.Message) // Test creating a file without a message createFileOptions = getCreateFileOptions() @@ -213,7 +237,7 @@ func TestAPICreateFile(t *testing.T) { resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Add " + treePath + "\n" - assert.EqualValues(t, expectedMessage, fileResponse.Commit.Message) + assert.Equal(t, expectedMessage, fileResponse.Commit.Message) // Test trying to create a file that already exists, should fail createFileOptions = getCreateFileOptions() @@ -285,19 +309,27 @@ func TestAPICreateFile(t *testing.T) { resp = MakeRequest(t, req, http.StatusCreated) emptyRepo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user2", Name: "empty-repo"}) // public repo gitRepo, _ := gitrepo.OpenRepository(t.Context(), emptyRepo) + defer gitRepo.Close() commitID, _ := gitRepo.GetBranchCommitID(createFileOptions.NewBranchName) latestCommit, _ := gitRepo.GetCommitByPath(treePath) - expectedFileResponse := getExpectedFileResponseForCreate("user2/empty-repo", commitID, treePath, latestCommit.ID.String()) + expectedFileResponse := getExpectedFileResponseForCreate(apiFileResponseInfo{ + repoFullName: "user2/empty-repo", + commitID: commitID, + treePath: treePath, + lastCommitSHA: latestCommit.ID.String(), + lastCommitterWhen: latestCommit.Committer.When, + lastAuthorWhen: latestCommit.Author.When, + }) DecodeJSON(t, resp, &fileResponse) - assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Date, fileResponse.Commit.Author.Date) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Email, fileResponse.Commit.Committer.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Name, fileResponse.Commit.Committer.Name) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Date, fileResponse.Commit.Committer.Date) - gitRepo.Close() + normalizeFileContentResponseCommitTime(fileResponse.Content) + assert.Equal(t, expectedFileResponse.Content, fileResponse.Content) + assert.Equal(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) + assert.Equal(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) + assert.Equal(t, expectedFileResponse.Commit.Author.Date, fileResponse.Commit.Author.Date) + assert.Equal(t, expectedFileResponse.Commit.Committer.Email, fileResponse.Commit.Committer.Email) + assert.Equal(t, expectedFileResponse.Commit.Committer.Name, fileResponse.Commit.Committer.Name) + assert.Equal(t, expectedFileResponse.Commit.Committer.Date, fileResponse.Commit.Committer.Date) }) } diff --git a/tests/integration/api_repo_file_delete_test.go b/tests/integration/api_repo_file_delete_test.go index 7c93307e19..47730cd933 100644 --- a/tests/integration/api_repo_file_delete_test.go +++ b/tests/integration/api_repo_file_delete_test.go @@ -87,7 +87,7 @@ func TestAPIDeleteFile(t *testing.T) { DecodeJSON(t, resp, &fileResponse) assert.NotNil(t, fileResponse) assert.Nil(t, fileResponse.Content) - assert.EqualValues(t, deleteFileOptions.Message+"\n", fileResponse.Commit.Message) + assert.Equal(t, deleteFileOptions.Message+"\n", fileResponse.Commit.Message) // Test deleting file without a message fileID++ @@ -100,7 +100,7 @@ func TestAPIDeleteFile(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Delete " + treePath + "\n" - assert.EqualValues(t, expectedMessage, fileResponse.Commit.Message) + assert.Equal(t, expectedMessage, fileResponse.Commit.Message) // Test deleting a file with the wrong SHA fileID++ diff --git a/tests/integration/api_repo_file_update_test.go b/tests/integration/api_repo_file_update_test.go index c8ce94a3f5..1605cfbd0b 100644 --- a/tests/integration/api_repo_file_update_test.go +++ b/tests/integration/api_repo_file_update_test.go @@ -8,7 +8,7 @@ import ( "fmt" "net/http" "net/url" - "path/filepath" + "path" "testing" auth_model "code.gitea.io/gitea/models/auth" @@ -47,28 +47,30 @@ func getUpdateFileOptions() *api.UpdateFileOptions { } } -func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) *api.FileResponse { +func getExpectedFileResponseForUpdate(info apiFileResponseInfo) *api.FileResponse { sha := "08bd14b2e2852529157324de9c226b3364e76136" encoding := "base64" content := "VGhpcyBpcyB1cGRhdGVkIHRleHQ=" - selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + treePath + "?ref=master" - htmlURL := setting.AppURL + "user2/repo1/src/branch/master/" + treePath + selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + info.treePath + "?ref=master" + htmlURL := setting.AppURL + "user2/repo1/src/branch/master/" + info.treePath gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha - downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath - return &api.FileResponse{ + downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + info.treePath + ret := &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - LastCommitSHA: lastCommitSHA, - Type: "file", - Size: 20, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: path.Base(info.treePath), + Path: info.treePath, + SHA: sha, + LastCommitSHA: info.lastCommitSHA, + LastCommitterDate: info.lastCommitterWhen, + LastAuthorDate: info.lastAuthorWhen, + Type: "file", + Size: 20, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -77,10 +79,10 @@ func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) }, Commit: &api.FileCommitResponse{ CommitMeta: api.CommitMeta{ - URL: setting.AppURL + "api/v1/repos/user2/repo1/git/commits/" + commitID, - SHA: commitID, + URL: setting.AppURL + "api/v1/repos/user2/repo1/git/commits/" + info.commitID, + SHA: info.commitID, }, - HTMLURL: setting.AppURL + "user2/repo1/commit/" + commitID, + HTMLURL: setting.AppURL + "user2/repo1/commit/" + info.commitID, Author: &api.CommitUser{ Identity: api.Identity{ Name: "John Doe", @@ -102,6 +104,8 @@ func getExpectedFileResponseForUpdate(commitID, treePath, lastCommitSHA string) Payload: "", }, } + normalizeFileContentResponseCommitTime(ret.Content) + return ret } func TestAPIUpdateFile(t *testing.T) { @@ -135,17 +139,24 @@ func TestAPIUpdateFile(t *testing.T) { AddTokenAuth(token2) resp := MakeRequest(t, req, http.StatusOK) gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo1) + defer gitRepo.Close() commitID, _ := gitRepo.GetBranchCommitID(updateFileOptions.NewBranchName) lasCommit, _ := gitRepo.GetCommitByPath(treePath) - expectedFileResponse := getExpectedFileResponseForUpdate(commitID, treePath, lasCommit.ID.String()) + expectedFileResponse := getExpectedFileResponseForUpdate(apiFileResponseInfo{ + commitID: commitID, + treePath: treePath, + lastCommitSHA: lasCommit.ID.String(), + lastCommitterWhen: lasCommit.Committer.When, + lastAuthorWhen: lasCommit.Author.When, + }) var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) - assert.EqualValues(t, expectedFileResponse.Content, fileResponse.Content) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) - gitRepo.Close() + normalizeFileContentResponseCommitTime(fileResponse.Content) + assert.Equal(t, expectedFileResponse.Content, fileResponse.Content) + assert.Equal(t, expectedFileResponse.Commit.SHA, fileResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, fileResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Commit.Author.Email, fileResponse.Commit.Author.Email) + assert.Equal(t, expectedFileResponse.Commit.Author.Name, fileResponse.Commit.Author.Name) } // Test updating a file in a new branch @@ -163,10 +174,10 @@ func TestAPIUpdateFile(t *testing.T) { expectedSHA := "08bd14b2e2852529157324de9c226b3364e76136" expectedHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/new_branch/update/file%d.txt", fileID) expectedDownloadURL := fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/new_branch/update/file%d.txt", fileID) - assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA) - assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) - assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) - assert.EqualValues(t, updateFileOptions.Message+"\n", fileResponse.Commit.Message) + assert.Equal(t, expectedSHA, fileResponse.Content.SHA) + assert.Equal(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) + assert.Equal(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) + assert.Equal(t, updateFileOptions.Message+"\n", fileResponse.Commit.Message) // Test updating a file and renaming it updateFileOptions = getUpdateFileOptions() @@ -183,9 +194,9 @@ func TestAPIUpdateFile(t *testing.T) { expectedSHA = "08bd14b2e2852529157324de9c226b3364e76136" expectedHTMLURL = fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/master/rename/update/file%d.txt", fileID) expectedDownloadURL = fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/master/rename/update/file%d.txt", fileID) - assert.EqualValues(t, expectedSHA, fileResponse.Content.SHA) - assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) - assert.EqualValues(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) + assert.Equal(t, expectedSHA, fileResponse.Content.SHA) + assert.Equal(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) + assert.Equal(t, expectedDownloadURL, *fileResponse.Content.DownloadURL) // Test updating a file without a message updateFileOptions = getUpdateFileOptions() @@ -199,7 +210,7 @@ func TestAPIUpdateFile(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &fileResponse) expectedMessage := "Update " + treePath + "\n" - assert.EqualValues(t, expectedMessage, fileResponse.Commit.Message) + assert.Equal(t, expectedMessage, fileResponse.Commit.Message) // Test updating a file with the wrong SHA fileID++ diff --git a/tests/integration/api_repo_files_change_test.go b/tests/integration/api_repo_files_change_test.go index aca58025d2..999bcdc680 100644 --- a/tests/integration/api_repo_files_change_test.go +++ b/tests/integration/api_repo_files_change_test.go @@ -77,51 +77,56 @@ func TestAPIChangeFiles(t *testing.T) { token4 := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) // Test changing files in repo1 which user2 owns, try both with branch and empty branch - for _, branch := range [...]string{ - "master", // Branch - "", // Empty branch - } { - fileID++ - createTreePath := fmt.Sprintf("new/file%d.txt", fileID) - updateTreePath := fmt.Sprintf("update/file%d.txt", fileID) - deleteTreePath := fmt.Sprintf("delete/file%d.txt", fileID) - createFile(user2, repo1, updateTreePath) - createFile(user2, repo1, deleteTreePath) - changeFilesOptions := getChangeFilesOptions() - changeFilesOptions.BranchName = branch - changeFilesOptions.Files[0].Path = createTreePath - changeFilesOptions.Files[1].Path = updateTreePath - changeFilesOptions.Files[2].Path = deleteTreePath - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo1.Name), &changeFilesOptions). - AddTokenAuth(token2) - resp := MakeRequest(t, req, http.StatusCreated) - gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo1) - commitID, _ := gitRepo.GetBranchCommitID(changeFilesOptions.NewBranchName) - createLasCommit, _ := gitRepo.GetCommitByPath(createTreePath) - updateLastCommit, _ := gitRepo.GetCommitByPath(updateTreePath) - expectedCreateFileResponse := getExpectedFileResponseForCreate(fmt.Sprintf("%v/%v", user2.Name, repo1.Name), commitID, createTreePath, createLasCommit.ID.String()) - expectedUpdateFileResponse := getExpectedFileResponseForUpdate(commitID, updateTreePath, updateLastCommit.ID.String()) - var filesResponse api.FilesResponse - DecodeJSON(t, resp, &filesResponse) - - // check create file - assert.EqualValues(t, expectedCreateFileResponse.Content, filesResponse.Files[0]) - - // check update file - assert.EqualValues(t, expectedUpdateFileResponse.Content, filesResponse.Files[1]) - - // test commit info - assert.EqualValues(t, expectedCreateFileResponse.Commit.SHA, filesResponse.Commit.SHA) - assert.EqualValues(t, expectedCreateFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedCreateFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) - assert.EqualValues(t, expectedCreateFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) - assert.EqualValues(t, expectedCreateFileResponse.Commit.Committer.Email, filesResponse.Commit.Committer.Email) - assert.EqualValues(t, expectedCreateFileResponse.Commit.Committer.Name, filesResponse.Commit.Committer.Name) - - // test delete file - assert.Nil(t, filesResponse.Files[2]) - - gitRepo.Close() + for _, branch := range []string{"master", ""} { + t.Run("Branch-"+branch, func(t *testing.T) { + fileID++ + createTreePath := fmt.Sprintf("new/file%d.txt", fileID) + updateTreePath := fmt.Sprintf("update/file%d.txt", fileID) + deleteTreePath := fmt.Sprintf("delete/file%d.txt", fileID) + _, _ = createFile(user2, repo1, updateTreePath) + _, _ = createFile(user2, repo1, deleteTreePath) + changeFilesOptions := getChangeFilesOptions() + changeFilesOptions.BranchName = branch + changeFilesOptions.Files[0].Path = createTreePath + changeFilesOptions.Files[1].Path = updateTreePath + changeFilesOptions.Files[2].Path = deleteTreePath + req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/repos/%s/%s/contents", user2.Name, repo1.Name), &changeFilesOptions). + AddTokenAuth(token2) + resp := MakeRequest(t, req, http.StatusCreated) + gitRepo, _ := gitrepo.OpenRepository(t.Context(), repo1) + defer gitRepo.Close() + commitID, _ := gitRepo.GetBranchCommitID(changeFilesOptions.NewBranchName) + createLasCommit, _ := gitRepo.GetCommitByPath(createTreePath) + updateLastCommit, _ := gitRepo.GetCommitByPath(updateTreePath) + expectedCreateFileResponse := getExpectedFileResponseForCreate(apiFileResponseInfo{ + repoFullName: fmt.Sprintf("%s/%s", user2.Name, repo1.Name), + commitID: commitID, + treePath: createTreePath, + lastCommitSHA: createLasCommit.ID.String(), + lastCommitterWhen: createLasCommit.Committer.When, + lastAuthorWhen: createLasCommit.Author.When, + }) + expectedUpdateFileResponse := getExpectedFileResponseForUpdate(apiFileResponseInfo{ + commitID: commitID, + treePath: updateTreePath, + lastCommitSHA: updateLastCommit.ID.String(), + lastCommitterWhen: updateLastCommit.Committer.When, + lastAuthorWhen: updateLastCommit.Author.When, + }) + var filesResponse api.FilesResponse + DecodeJSON(t, resp, &filesResponse) + normalizeFileContentResponseCommitTime(filesResponse.Files[0]) + normalizeFileContentResponseCommitTime(filesResponse.Files[1]) + assert.Equal(t, expectedCreateFileResponse.Content, filesResponse.Files[0]) // check create file + assert.Equal(t, expectedUpdateFileResponse.Content, filesResponse.Files[1]) // check update file + assert.Equal(t, expectedCreateFileResponse.Commit.SHA, filesResponse.Commit.SHA) + assert.Equal(t, expectedCreateFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) + assert.Equal(t, expectedCreateFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) + assert.Equal(t, expectedCreateFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) + assert.Equal(t, expectedCreateFileResponse.Commit.Committer.Email, filesResponse.Commit.Committer.Email) + assert.Equal(t, expectedCreateFileResponse.Commit.Committer.Name, filesResponse.Commit.Committer.Name) + assert.Nil(t, filesResponse.Files[2]) // test delete file + }) } // Test changing files in a new branch @@ -149,15 +154,15 @@ func TestAPIChangeFiles(t *testing.T) { expectedUpdateSHA := "08bd14b2e2852529157324de9c226b3364e76136" expectedUpdateHTMLURL := fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/new_branch/update/file%d.txt", fileID) expectedUpdateDownloadURL := fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/new_branch/update/file%d.txt", fileID) - assert.EqualValues(t, expectedCreateSHA, filesResponse.Files[0].SHA) - assert.EqualValues(t, expectedCreateHTMLURL, *filesResponse.Files[0].HTMLURL) - assert.EqualValues(t, expectedCreateDownloadURL, *filesResponse.Files[0].DownloadURL) - assert.EqualValues(t, expectedUpdateSHA, filesResponse.Files[1].SHA) - assert.EqualValues(t, expectedUpdateHTMLURL, *filesResponse.Files[1].HTMLURL) - assert.EqualValues(t, expectedUpdateDownloadURL, *filesResponse.Files[1].DownloadURL) + assert.Equal(t, expectedCreateSHA, filesResponse.Files[0].SHA) + assert.Equal(t, expectedCreateHTMLURL, *filesResponse.Files[0].HTMLURL) + assert.Equal(t, expectedCreateDownloadURL, *filesResponse.Files[0].DownloadURL) + assert.Equal(t, expectedUpdateSHA, filesResponse.Files[1].SHA) + assert.Equal(t, expectedUpdateHTMLURL, *filesResponse.Files[1].HTMLURL) + assert.Equal(t, expectedUpdateDownloadURL, *filesResponse.Files[1].DownloadURL) assert.Nil(t, filesResponse.Files[2]) - assert.EqualValues(t, changeFilesOptions.Message+"\n", filesResponse.Commit.Message) + assert.Equal(t, changeFilesOptions.Message+"\n", filesResponse.Commit.Message) // Test updating a file and renaming it changeFilesOptions = getChangeFilesOptions() @@ -175,9 +180,9 @@ func TestAPIChangeFiles(t *testing.T) { expectedUpdateSHA = "08bd14b2e2852529157324de9c226b3364e76136" expectedUpdateHTMLURL = fmt.Sprintf(setting.AppURL+"user2/repo1/src/branch/master/rename/update/file%d.txt", fileID) expectedUpdateDownloadURL = fmt.Sprintf(setting.AppURL+"user2/repo1/raw/branch/master/rename/update/file%d.txt", fileID) - assert.EqualValues(t, expectedUpdateSHA, filesResponse.Files[0].SHA) - assert.EqualValues(t, expectedUpdateHTMLURL, *filesResponse.Files[0].HTMLURL) - assert.EqualValues(t, expectedUpdateDownloadURL, *filesResponse.Files[0].DownloadURL) + assert.Equal(t, expectedUpdateSHA, filesResponse.Files[0].SHA) + assert.Equal(t, expectedUpdateHTMLURL, *filesResponse.Files[0].HTMLURL) + assert.Equal(t, expectedUpdateDownloadURL, *filesResponse.Files[0].DownloadURL) // Test updating a file without a message changeFilesOptions = getChangeFilesOptions() @@ -197,7 +202,7 @@ func TestAPIChangeFiles(t *testing.T) { resp = MakeRequest(t, req, http.StatusCreated) DecodeJSON(t, resp, &filesResponse) expectedMessage := fmt.Sprintf("Add %v\nUpdate %v\nDelete %v\n", createTreePath, updateTreePath, deleteTreePath) - assert.EqualValues(t, expectedMessage, filesResponse.Commit.Message) + assert.Equal(t, expectedMessage, filesResponse.Commit.Message) // Test updating a file with the wrong SHA fileID++ diff --git a/tests/integration/api_repo_get_contents_list_test.go b/tests/integration/api_repo_get_contents_list_test.go index 1ba74490a3..9b192c6304 100644 --- a/tests/integration/api_repo_get_contents_list_test.go +++ b/tests/integration/api_repo_get_contents_list_test.go @@ -6,8 +6,9 @@ package integration import ( "net/http" "net/url" - "path/filepath" + "path" "testing" + "time" auth_model "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" @@ -31,16 +32,18 @@ func getExpectedContentsListResponseForContents(ref, refType, lastCommitSHA stri downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath return []*api.ContentsResponse{ { - Name: filepath.Base(treePath), - Path: treePath, - SHA: sha, - LastCommitSHA: lastCommitSHA, - Type: "file", - Size: 30, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: path.Base(treePath), + Path: treePath, + SHA: sha, + LastCommitSHA: lastCommitSHA, + LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + Type: "file", + Size: 30, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -99,7 +102,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { lastCommit, err := gitRepo.GetCommitByPath("README.md") assert.NoError(t, err) expectedContentsListResponse := getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) + assert.Equal(t, expectedContentsListResponse, contentsListResponse) // No ref refType = "branch" @@ -109,7 +112,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { assert.NotNil(t, contentsListResponse) expectedContentsListResponse = getExpectedContentsListResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String()) - assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) + assert.Equal(t, expectedContentsListResponse, contentsListResponse) // ref is the branch we created above in setup ref = newBranch @@ -123,7 +126,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { lastCommit, err = branchCommit.GetCommitByPath("README.md") assert.NoError(t, err) expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) + assert.Equal(t, expectedContentsListResponse, contentsListResponse) // ref is the new tag we created above in setup ref = newTag @@ -137,7 +140,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { lastCommit, err = tagCommit.GetCommitByPath("README.md") assert.NoError(t, err) expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) + assert.Equal(t, expectedContentsListResponse, contentsListResponse) // ref is a commit ref = commitID @@ -147,7 +150,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) { DecodeJSON(t, resp, &contentsListResponse) assert.NotNil(t, contentsListResponse) expectedContentsListResponse = getExpectedContentsListResponseForContents(ref, refType, commitID) - assert.EqualValues(t, expectedContentsListResponse, contentsListResponse) + assert.Equal(t, expectedContentsListResponse, contentsListResponse) // Test file contents a file with a bad ref ref = "badref" diff --git a/tests/integration/api_repo_get_contents_test.go b/tests/integration/api_repo_get_contents_test.go index d0f61da0c0..1571787886 100644 --- a/tests/integration/api_repo_get_contents_test.go +++ b/tests/integration/api_repo_get_contents_test.go @@ -8,6 +8,7 @@ import ( "net/http" "net/url" "testing" + "time" auth_model "code.gitea.io/gitea/models/auth" repo_model "code.gitea.io/gitea/models/repo" @@ -33,18 +34,20 @@ func getExpectedContentsResponseForContents(ref, refType, lastCommitSHA string) gitURL := setting.AppURL + "api/v1/repos/user2/repo1/git/blobs/" + sha downloadURL := setting.AppURL + "user2/repo1/raw/" + refType + "/" + ref + "/" + treePath return &api.ContentsResponse{ - Name: treePath, - Path: treePath, - SHA: sha, - LastCommitSHA: lastCommitSHA, - Type: "file", - Size: 30, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: treePath, + Path: treePath, + SHA: sha, + LastCommitSHA: lastCommitSHA, + LastCommitterDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + LastAuthorDate: time.Date(2017, time.March, 19, 16, 47, 59, 0, time.FixedZone("", -14400)), + Type: "file", + Size: 30, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -102,7 +105,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { assert.NotNil(t, contentsResponse) lastCommit, _ := gitRepo.GetCommitByPath("README.md") expectedContentsResponse := getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, *expectedContentsResponse, contentsResponse) + assert.Equal(t, *expectedContentsResponse, contentsResponse) // No ref refType = "branch" @@ -111,7 +114,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) expectedContentsResponse = getExpectedContentsResponseForContents(repo1.DefaultBranch, refType, lastCommit.ID.String()) - assert.EqualValues(t, *expectedContentsResponse, contentsResponse) + assert.Equal(t, *expectedContentsResponse, contentsResponse) // ref is the branch we created above in setup ref = newBranch @@ -123,7 +126,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { branchCommit, _ := gitRepo.GetBranchCommit(ref) lastCommit, _ = branchCommit.GetCommitByPath("README.md") expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, *expectedContentsResponse, contentsResponse) + assert.Equal(t, *expectedContentsResponse, contentsResponse) // ref is the new tag we created above in setup ref = newTag @@ -135,7 +138,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { tagCommit, _ := gitRepo.GetTagCommit(ref) lastCommit, _ = tagCommit.GetCommitByPath("README.md") expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, lastCommit.ID.String()) - assert.EqualValues(t, *expectedContentsResponse, contentsResponse) + assert.Equal(t, *expectedContentsResponse, contentsResponse) // ref is a commit ref = commitID @@ -145,7 +148,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) { DecodeJSON(t, resp, &contentsResponse) assert.NotNil(t, contentsResponse) expectedContentsResponse = getExpectedContentsResponseForContents(ref, refType, commitID) - assert.EqualValues(t, *expectedContentsResponse, contentsResponse) + assert.Equal(t, *expectedContentsResponse, contentsResponse) // Test file contents a file with a bad ref ref = "badref" @@ -178,22 +181,22 @@ func TestAPIGetContentsRefFormats(t *testing.T) { resp := MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file), http.StatusOK) raw, err := io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, content, string(raw)) + assert.Equal(t, content, string(raw)) resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+sha+"/"+file), http.StatusOK) raw, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, content, string(raw)) + assert.Equal(t, content, string(raw)) resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file+"?ref="+sha), http.StatusOK) raw, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, content, string(raw)) + assert.Equal(t, content, string(raw)) resp = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/"+file+"?ref=master"), http.StatusOK) raw, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, content, string(raw)) + assert.Equal(t, content, string(raw)) _ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/docs/README.md?ref=main"), http.StatusNotFound) _ = MakeRequest(t, NewRequest(t, http.MethodGet, "/api/v1/repos/user2/repo1/raw/README.md?ref=main"), http.StatusOK) diff --git a/tests/integration/api_repo_git_commits_test.go b/tests/integration/api_repo_git_commits_test.go index c4c626eb49..a1584d4629 100644 --- a/tests/integration/api_repo_git_commits_test.go +++ b/tests/integration/api_repo_git_commits_test.go @@ -72,12 +72,12 @@ func TestAPIReposGitCommitList(t *testing.T) { DecodeJSON(t, resp, &apiData) assert.Len(t, apiData, 2) - assert.EqualValues(t, "cfe3b3c1fd36fba04f9183287b106497e1afe986", apiData[0].CommitMeta.SHA) + assert.Equal(t, "cfe3b3c1fd36fba04f9183287b106497e1afe986", apiData[0].CommitMeta.SHA) compareCommitFiles(t, []string{"link_hi", "test.csv"}, apiData[0].Files) - assert.EqualValues(t, "c8e31bc7688741a5287fcde4fbb8fc129ca07027", apiData[1].CommitMeta.SHA) + assert.Equal(t, "c8e31bc7688741a5287fcde4fbb8fc129ca07027", apiData[1].CommitMeta.SHA) compareCommitFiles(t, []string{"test.csv"}, apiData[1].Files) - assert.EqualValues(t, "2", resp.Header().Get("X-Total")) + assert.Equal(t, "2", resp.Header().Get("X-Total")) } func TestAPIReposGitCommitListNotMaster(t *testing.T) { @@ -96,14 +96,14 @@ func TestAPIReposGitCommitListNotMaster(t *testing.T) { DecodeJSON(t, resp, &apiData) assert.Len(t, apiData, 3) - assert.EqualValues(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) + assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", apiData[0].CommitMeta.SHA) compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) - assert.EqualValues(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", apiData[1].CommitMeta.SHA) + assert.Equal(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", apiData[1].CommitMeta.SHA) compareCommitFiles(t, []string{"readme.md"}, apiData[1].Files) - assert.EqualValues(t, "5099b81332712fe655e34e8dd63574f503f61811", apiData[2].CommitMeta.SHA) + assert.Equal(t, "5099b81332712fe655e34e8dd63574f503f61811", apiData[2].CommitMeta.SHA) compareCommitFiles(t, []string{"readme.md"}, apiData[2].Files) - assert.EqualValues(t, "3", resp.Header().Get("X-Total")) + assert.Equal(t, "3", resp.Header().Get("X-Total")) } func TestAPIReposGitCommitListPage2Empty(t *testing.T) { @@ -177,7 +177,7 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { reqDiff := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.diff", user.Name). AddTokenAuth(token) resp := MakeRequest(t, reqDiff, http.StatusOK) - assert.EqualValues(t, + assert.Equal(t, "commit f27c2b2b03dcab38beaf89b0ab4ff61f6de63441\nAuthor: User2 \nDate: Sun Aug 6 19:55:01 2017 +0200\n\n good signed commit\n\ndiff --git a/readme.md b/readme.md\nnew file mode 100644\nindex 0000000..458121c\n--- /dev/null\n+++ b/readme.md\n@@ -0,0 +1 @@\n+good sign\n", resp.Body.String()) @@ -185,7 +185,7 @@ func TestDownloadCommitDiffOrPatch(t *testing.T) { reqPatch := NewRequestf(t, "GET", "/api/v1/repos/%s/repo16/git/commits/f27c2b2b03dcab38beaf89b0ab4ff61f6de63441.patch", user.Name). AddTokenAuth(token) resp = MakeRequest(t, reqPatch, http.StatusOK) - assert.EqualValues(t, + assert.Equal(t, "From f27c2b2b03dcab38beaf89b0ab4ff61f6de63441 Mon Sep 17 00:00:00 2001\nFrom: User2 \nDate: Sun, 6 Aug 2017 19:55:01 +0200\nSubject: [PATCH] good signed commit\n\n---\n readme.md | 1 +\n 1 file changed, 1 insertion(+)\n create mode 100644 readme.md\n\ndiff --git a/readme.md b/readme.md\nnew file mode 100644\nindex 0000000..458121c\n--- /dev/null\n+++ b/readme.md\n@@ -0,0 +1 @@\n+good sign\n", resp.Body.String()) } @@ -208,7 +208,7 @@ func TestGetFileHistory(t *testing.T) { assert.Equal(t, "f27c2b2b03dcab38beaf89b0ab4ff61f6de63441", apiData[0].CommitMeta.SHA) compareCommitFiles(t, []string{"readme.md"}, apiData[0].Files) - assert.EqualValues(t, "1", resp.Header().Get("X-Total")) + assert.Equal(t, "1", resp.Header().Get("X-Total")) } func TestGetFileHistoryNotOnMaster(t *testing.T) { @@ -229,5 +229,5 @@ func TestGetFileHistoryNotOnMaster(t *testing.T) { assert.Equal(t, "c8e31bc7688741a5287fcde4fbb8fc129ca07027", apiData[0].CommitMeta.SHA) compareCommitFiles(t, []string{"test.csv"}, apiData[0].Files) - assert.EqualValues(t, "1", resp.Header().Get("X-Total")) + assert.Equal(t, "1", resp.Header().Get("X-Total")) } diff --git a/tests/integration/api_repo_lfs_locks_test.go b/tests/integration/api_repo_lfs_locks_test.go index 4ba01e6d9b..161fa45dc6 100644 --- a/tests/integration/api_repo_lfs_locks_test.go +++ b/tests/integration/api_repo_lfs_locks_test.go @@ -112,7 +112,7 @@ func TestAPILFSLocksLogged(t *testing.T) { var lfsLock api.LFSLockResponse DecodeJSON(t, resp, &lfsLock) assert.Equal(t, test.user.Name, lfsLock.Lock.Owner.Name) - assert.EqualValues(t, lfsLock.Lock.LockedAt.Format(time.RFC3339), lfsLock.Lock.LockedAt.Format(time.RFC3339Nano)) // locked at should be rounded to second + assert.Equal(t, lfsLock.Lock.LockedAt.Format(time.RFC3339), lfsLock.Lock.LockedAt.Format(time.RFC3339Nano)) // locked at should be rounded to second for _, id := range test.addTime { resultsTests[id].locksTimes = append(resultsTests[id].locksTimes, time.Now()) } @@ -129,9 +129,9 @@ func TestAPILFSLocksLogged(t *testing.T) { DecodeJSON(t, resp, &lfsLocks) assert.Len(t, lfsLocks.Locks, test.totalCount) for i, lock := range lfsLocks.Locks { - assert.EqualValues(t, test.locksOwners[i].Name, lock.Owner.Name) + assert.Equal(t, test.locksOwners[i].Name, lock.Owner.Name) assert.WithinDuration(t, test.locksTimes[i], lock.LockedAt, 10*time.Second) - assert.EqualValues(t, lock.LockedAt.Format(time.RFC3339), lock.LockedAt.Format(time.RFC3339Nano)) // locked at should be rounded to second + assert.Equal(t, lock.LockedAt.Format(time.RFC3339), lock.LockedAt.Format(time.RFC3339Nano)) // locked at should be rounded to second } req = NewRequestWithJSON(t, "POST", fmt.Sprintf("/%s.git/info/lfs/locks/verify", test.repo.FullName()), map[string]string{}) @@ -143,7 +143,7 @@ func TestAPILFSLocksLogged(t *testing.T) { assert.Len(t, lfsLocksVerify.Ours, test.oursCount) assert.Len(t, lfsLocksVerify.Theirs, test.theirsCount) for _, lock := range lfsLocksVerify.Ours { - assert.EqualValues(t, test.user.Name, lock.Owner.Name) + assert.Equal(t, test.user.Name, lock.Owner.Name) deleteTests = append(deleteTests, struct { user *user_model.User repo *repo_model.Repository diff --git a/tests/integration/api_repo_lfs_migrate_test.go b/tests/integration/api_repo_lfs_migrate_test.go index 8b4d79db02..6ca6f9afab 100644 --- a/tests/integration/api_repo_lfs_migrate_test.go +++ b/tests/integration/api_repo_lfs_migrate_test.go @@ -40,7 +40,7 @@ func TestAPIRepoLFSMigrateLocal(t *testing.T) { LFS: true, }).AddTokenAuth(token) resp := MakeRequest(t, req, NoExpectedStatus) - assert.EqualValues(t, http.StatusCreated, resp.Code) + assert.Equal(t, http.StatusCreated, resp.Code) store := lfs.NewContentStore() ok, _ := store.Verify(lfs.Pointer{Oid: "fb8f7d8435968c4f82a726a92395be4d16f2f63116caf36c8ad35c60831ab041", Size: 6}) diff --git a/tests/integration/api_repo_raw_test.go b/tests/integration/api_repo_raw_test.go index e5f83d1c80..e9d741925f 100644 --- a/tests/integration/api_repo_raw_test.go +++ b/tests/integration/api_repo_raw_test.go @@ -30,11 +30,11 @@ func TestAPIReposRaw(t *testing.T) { req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/%s/README.md", user.Name, ref). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) + assert.Equal(t, "file", resp.Header().Get("x-gitea-object-type")) } // Test default branch req := NewRequestf(t, "GET", "/api/v1/repos/%s/repo1/raw/README.md", user.Name). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, "file", resp.Header().Get("x-gitea-object-type")) + assert.Equal(t, "file", resp.Header().Get("x-gitea-object-type")) } diff --git a/tests/integration/api_repo_tags_test.go b/tests/integration/api_repo_tags_test.go index a7f021ca4f..3932a8ba2b 100644 --- a/tests/integration/api_repo_tags_test.go +++ b/tests/integration/api_repo_tags_test.go @@ -48,10 +48,10 @@ func TestAPIRepoTags(t *testing.T) { assert.Len(t, tags, 2) for _, tag := range tags { if tag.Name != "v1.1" { - assert.EqualValues(t, newTag.Name, tag.Name) - assert.EqualValues(t, newTag.Message, tag.Message) - assert.EqualValues(t, "nice!\nand some text", tag.Message) - assert.EqualValues(t, newTag.Commit.SHA, tag.Commit.SHA) + assert.Equal(t, newTag.Name, tag.Name) + assert.Equal(t, newTag.Message, tag.Message) + assert.Equal(t, "nice!\nand some text", tag.Message) + assert.Equal(t, newTag.Commit.SHA, tag.Commit.SHA) } } @@ -61,7 +61,7 @@ func TestAPIRepoTags(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) var tag *api.Tag DecodeJSON(t, resp, &tag) - assert.EqualValues(t, newTag, tag) + assert.Equal(t, newTag, tag) // delete tag delReq := NewRequestf(t, "DELETE", "/api/v1/repos/%s/%s/tags/%s", user.Name, repoName, newTag.Name). diff --git a/tests/integration/api_repo_teams_test.go b/tests/integration/api_repo_teams_test.go index 07d065b02b..143e3dd29f 100644 --- a/tests/integration/api_repo_teams_test.go +++ b/tests/integration/api_repo_teams_test.go @@ -37,15 +37,15 @@ func TestAPIRepoTeams(t *testing.T) { var teams []*api.Team DecodeJSON(t, res, &teams) if assert.Len(t, teams, 2) { - assert.EqualValues(t, "Owners", teams[0].Name) + assert.Equal(t, "Owners", teams[0].Name) assert.True(t, teams[0].CanCreateOrgRepo) assert.True(t, util.SliceSortedEqual(unit.AllUnitKeyNames(), teams[0].Units), "%v == %v", unit.AllUnitKeyNames(), teams[0].Units) - assert.EqualValues(t, "owner", teams[0].Permission) + assert.Equal(t, "owner", teams[0].Permission) - assert.EqualValues(t, "test_team", teams[1].Name) + assert.Equal(t, "test_team", teams[1].Name) assert.False(t, teams[1].CanCreateOrgRepo) - assert.EqualValues(t, []string{"repo.issues"}, teams[1].Units) - assert.EqualValues(t, "write", teams[1].Permission) + assert.Equal(t, []string{"repo.issues"}, teams[1].Units) + assert.Equal(t, "write", teams[1].Permission) } // IsTeam @@ -54,7 +54,7 @@ func TestAPIRepoTeams(t *testing.T) { res = MakeRequest(t, req, http.StatusOK) var team *api.Team DecodeJSON(t, res, &team) - assert.EqualValues(t, teams[1], team) + assert.Equal(t, teams[1], team) req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/teams/%s", publicOrgRepo.FullName(), "NonExistingTeam")). AddTokenAuth(token) diff --git a/tests/integration/api_repo_test.go b/tests/integration/api_repo_test.go index 22f26d87d4..672c2a2c8b 100644 --- a/tests/integration/api_repo_test.go +++ b/tests/integration/api_repo_test.go @@ -37,7 +37,7 @@ func TestAPIUserReposNotLogin(t *testing.T) { unittest.Cond("is_private = ?", false)) assert.Len(t, apiRepos, expectedLen) for _, repo := range apiRepos { - assert.EqualValues(t, user.ID, repo.Owner.ID) + assert.Equal(t, user.ID, repo.Owner.ID) assert.False(t, repo.Private) } } @@ -45,7 +45,7 @@ func TestAPIUserReposNotLogin(t *testing.T) { func TestAPIUserReposWithWrongToken(t *testing.T) { defer tests.PrepareTestEnv(t)() user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}) - wrongToken := fmt.Sprintf("Bearer %s", "wrong_token") + wrongToken := "Bearer " + "wrong_token" req := NewRequestf(t, "GET", "/api/v1/users/%s/repos", user.Name). AddTokenAuth(wrongToken) resp := MakeRequest(t, req, http.StatusUnauthorized) @@ -266,25 +266,25 @@ func TestAPIViewRepo(t *testing.T) { resp := MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.EqualValues(t, 1, repo.ID) - assert.EqualValues(t, "repo1", repo.Name) - assert.EqualValues(t, 2, repo.Releases) - assert.EqualValues(t, 1, repo.OpenIssues) - assert.EqualValues(t, 3, repo.OpenPulls) + assert.Equal(t, "repo1", repo.Name) + assert.Equal(t, 2, repo.Releases) + assert.Equal(t, 1, repo.OpenIssues) + assert.Equal(t, 3, repo.OpenPulls) req = NewRequest(t, "GET", "/api/v1/repos/user12/repo10") resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.EqualValues(t, 10, repo.ID) - assert.EqualValues(t, "repo10", repo.Name) - assert.EqualValues(t, 1, repo.OpenPulls) - assert.EqualValues(t, 1, repo.Forks) + assert.Equal(t, "repo10", repo.Name) + assert.Equal(t, 1, repo.OpenPulls) + assert.Equal(t, 1, repo.Forks) req = NewRequest(t, "GET", "/api/v1/repos/user5/repo4") resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) assert.EqualValues(t, 4, repo.ID) - assert.EqualValues(t, "repo4", repo.Name) - assert.EqualValues(t, 1, repo.Stars) + assert.Equal(t, "repo4", repo.Name) + assert.Equal(t, 1, repo.Stars) } func TestAPIOrgRepos(t *testing.T) { @@ -337,9 +337,9 @@ func TestAPIOrgReposWithCodeUnitDisabled(t *testing.T) { var units []unit_model.Type units = append(units, unit_model.TypeCode) - if err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo21, nil, units); err != nil { - assert.Fail(t, "should have been able to delete code repository unit; failed to %v", err) - } + err := repo_service.UpdateRepositoryUnits(db.DefaultContext, repo21, nil, units) + assert.NoError(t, err, "should have been able to delete code repository unit") + assert.False(t, repo21.UnitEnabled(db.DefaultContext, unit_model.TypeCode)) session := loginUser(t, "user2") @@ -403,12 +403,12 @@ func TestAPIRepoMigrate(t *testing.T) { case "Remote visit addressed rate limitation.": t.Log("test hit github rate limitation") case "You can not import from disallowed hosts.": - assert.EqualValues(t, "private-ip", testCase.repoName) + assert.Equal(t, "private-ip", testCase.repoName) default: - assert.FailNow(t, "unexpected error '%v' on url '%s'", respJSON["message"], testCase.cloneURL) + assert.FailNow(t, "unexpected error", "unexpected error '%v' on url '%s'", respJSON["message"], testCase.cloneURL) } } else { - assert.EqualValues(t, testCase.expectedStatus, resp.Code) + assert.Equal(t, testCase.expectedStatus, resp.Code) } } } diff --git a/tests/integration/api_repo_topic_test.go b/tests/integration/api_repo_topic_test.go index a10e159b78..82d0c54ca8 100644 --- a/tests/integration/api_repo_topic_test.go +++ b/tests/integration/api_repo_topic_test.go @@ -30,7 +30,7 @@ func TestAPITopicSearch(t *testing.T) { res := MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 6) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // pagination search topics first page topics.TopicNames = nil @@ -40,7 +40,7 @@ func TestAPITopicSearch(t *testing.T) { res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 4) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // pagination search topics second page topics.TopicNames = nil @@ -50,7 +50,7 @@ func TestAPITopicSearch(t *testing.T) { res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 2) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // add keyword search query = url.Values{"page": []string{"1"}, "limit": []string{"4"}} @@ -66,8 +66,8 @@ func TestAPITopicSearch(t *testing.T) { DecodeJSON(t, res, &topics) if assert.Len(t, topics.TopicNames, 1) { assert.EqualValues(t, 2, topics.TopicNames[0].ID) - assert.EqualValues(t, "database", topics.TopicNames[0].Name) - assert.EqualValues(t, 1, topics.TopicNames[0].RepoCount) + assert.Equal(t, "database", topics.TopicNames[0].Name) + assert.Equal(t, 1, topics.TopicNames[0].RepoCount) } } diff --git a/tests/integration/api_settings_test.go b/tests/integration/api_settings_test.go index 9881578fba..6f433148f5 100644 --- a/tests/integration/api_settings_test.go +++ b/tests/integration/api_settings_test.go @@ -30,7 +30,7 @@ func TestAPIExposedSettings(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiSettings) - assert.EqualValues(t, &api.GeneralAPISettings{ + assert.Equal(t, &api.GeneralAPISettings{ MaxResponseItems: setting.API.MaxResponseItems, DefaultPagingNum: setting.API.DefaultPagingNum, DefaultGitTreesPerPage: setting.API.DefaultGitTreesPerPage, @@ -42,7 +42,7 @@ func TestAPIExposedSettings(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &repo) - assert.EqualValues(t, &api.GeneralRepoSettings{ + assert.Equal(t, &api.GeneralRepoSettings{ MirrorsDisabled: !setting.Mirror.Enabled, HTTPGitDisabled: setting.Repository.DisableHTTPGit, MigrationsDisabled: setting.Repository.DisableMigrations, @@ -55,7 +55,7 @@ func TestAPIExposedSettings(t *testing.T) { resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &attachment) - assert.EqualValues(t, &api.GeneralAttachmentSettings{ + assert.Equal(t, &api.GeneralAttachmentSettings{ Enabled: setting.Attachment.Enabled, AllowedTypes: setting.Attachment.AllowedTypes, MaxFiles: setting.Attachment.MaxFiles, diff --git a/tests/integration/api_team_test.go b/tests/integration/api_team_test.go index d14c66ff2c..a2a2f388fd 100644 --- a/tests/integration/api_team_test.go +++ b/tests/integration/api_team_test.go @@ -40,9 +40,9 @@ func TestAPITeam(t *testing.T) { var apiTeam api.Team DecodeJSON(t, resp, &apiTeam) - assert.EqualValues(t, team.ID, apiTeam.ID) + assert.Equal(t, team.ID, apiTeam.ID) assert.Equal(t, team.Name, apiTeam.Name) - assert.EqualValues(t, convert.ToOrganization(db.DefaultContext, org), apiTeam.Organization) + assert.Equal(t, convert.ToOrganization(db.DefaultContext, org), apiTeam.Organization) // non team member user will not access the teams details teamUser2 := unittest.AssertExistsAndLoadBean(t, &organization.TeamUser{ID: 3}) @@ -247,10 +247,10 @@ func checkTeamResponse(t *testing.T, testName string, apiTeam *api.Team, name, d if units != nil { sort.StringSlice(units).Sort() sort.StringSlice(apiTeam.Units).Sort() - assert.EqualValues(t, units, apiTeam.Units, "units") + assert.Equal(t, units, apiTeam.Units, "units") } if unitsMap != nil { - assert.EqualValues(t, unitsMap, apiTeam.UnitsMap, "unitsMap") + assert.Equal(t, unitsMap, apiTeam.UnitsMap, "unitsMap") } }) } diff --git a/tests/integration/api_team_user_test.go b/tests/integration/api_team_user_test.go index 6c80bc9f80..adc9831aa0 100644 --- a/tests/integration/api_team_user_test.go +++ b/tests/integration/api_team_user_test.go @@ -40,8 +40,8 @@ func TestAPITeamUser(t *testing.T) { expectedUser := convert.ToUser(db.DefaultContext, user, user) // test time via unix timestamp - assert.EqualValues(t, expectedUser.LastLogin.Unix(), user2.LastLogin.Unix()) - assert.EqualValues(t, expectedUser.Created.Unix(), user2.Created.Unix()) + assert.Equal(t, expectedUser.LastLogin.Unix(), user2.LastLogin.Unix()) + assert.Equal(t, expectedUser.Created.Unix(), user2.Created.Unix()) expectedUser.LastLogin = user2.LastLogin expectedUser.Created = user2.Created diff --git a/tests/integration/api_token_test.go b/tests/integration/api_token_test.go index 01d18ef6f1..1770358d21 100644 --- a/tests/integration/api_token_test.go +++ b/tests/integration/api_token_test.go @@ -507,7 +507,7 @@ func runTestCase(t *testing.T, testCase *requiredScopeTestCase, user *user_model } else if minRequiredLevel == auth_model.Write { unauthorizedLevel = auth_model.Read } else { - assert.FailNow(t, "Invalid test case: Unknown access token scope level: %v", minRequiredLevel) + assert.FailNow(t, "Invalid test case", "Unknown access token scope level: %v", minRequiredLevel) } } diff --git a/tests/integration/api_twofa_test.go b/tests/integration/api_twofa_test.go index 18e6fa91b7..b8052c0812 100644 --- a/tests/integration/api_twofa_test.go +++ b/tests/integration/api_twofa_test.go @@ -94,7 +94,7 @@ func TestBasicAuthWithWebAuthn(t *testing.T) { } var userParsed userResponse DecodeJSON(t, resp, &userParsed) - assert.EqualValues(t, "Basic authorization is not allowed while webAuthn enrolled", userParsed.Message) + assert.Equal(t, "Basic authorization is not allowed while webAuthn enrolled", userParsed.Message) // user32 has webauthn enrolled, he can't request git protocol with basic auth req = NewRequest(t, "GET", "/user2/repo1/info/refs") diff --git a/tests/integration/api_user_block_test.go b/tests/integration/api_user_block_test.go index ae6b9eb849..6f73b089df 100644 --- a/tests/integration/api_user_block_test.go +++ b/tests/integration/api_user_block_test.go @@ -76,7 +76,7 @@ func TestBlockUser(t *testing.T) { blockeeName := "user10" t.Run("Block", func(t *testing.T) { - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)) + req := NewRequest(t, "PUT", "/api/v1/user/blocks/"+blockeeName) MakeRequest(t, req, http.StatusUnauthorized) assert.EqualValues(t, 1, countStars(t, blockerID, blockeeID)) @@ -84,7 +84,7 @@ func TestBlockUser(t *testing.T) { assert.EqualValues(t, 1, countRepositoryTransfers(t, blockerID, blockeeID)) assert.EqualValues(t, 1, countCollaborations(t, blockerID, blockeeID)) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)). + req = NewRequest(t, "GET", "/api/v1/user/blocks/"+blockeeName). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusNotFound) @@ -97,15 +97,15 @@ func TestBlockUser(t *testing.T) { assert.EqualValues(t, 0, countRepositoryTransfers(t, blockerID, blockeeID)) assert.EqualValues(t, 0, countCollaborations(t, blockerID, blockeeID)) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)). + req = NewRequest(t, "GET", "/api/v1/user/blocks/"+blockeeName). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)). + req = NewRequest(t, "PUT", "/api/v1/user/blocks/"+blockeeName). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusBadRequest) // can't block blocked user - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/blocks/%s", "org3")). + req = NewRequest(t, "PUT", "/api/v1/user/blocks/"+"org3"). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusBadRequest) // can't block organization @@ -124,18 +124,18 @@ func TestBlockUser(t *testing.T) { }) t.Run("Unblock", func(t *testing.T) { - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)) + req := NewRequest(t, "DELETE", "/api/v1/user/blocks/"+blockeeName) MakeRequest(t, req, http.StatusUnauthorized) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)). + req = NewRequest(t, "DELETE", "/api/v1/user/blocks/"+blockeeName). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/blocks/%s", blockeeName)). + req = NewRequest(t, "DELETE", "/api/v1/user/blocks/"+blockeeName). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusBadRequest) - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/blocks/%s", "org3")). + req = NewRequest(t, "DELETE", "/api/v1/user/blocks/"+"org3"). AddTokenAuth(blockerToken) MakeRequest(t, req, http.StatusBadRequest) diff --git a/tests/integration/api_user_email_test.go b/tests/integration/api_user_email_test.go index 6441e2ed8e..5b6f0708ea 100644 --- a/tests/integration/api_user_email_test.go +++ b/tests/integration/api_user_email_test.go @@ -28,7 +28,7 @@ func TestAPIListEmails(t *testing.T) { var emails []*api.Email DecodeJSON(t, resp, &emails) - assert.EqualValues(t, []*api.Email{ + assert.Equal(t, []*api.Email{ { Email: "user2@example.com", Verified: true, @@ -66,7 +66,7 @@ func TestAPIAddEmail(t *testing.T) { var emails []*api.Email DecodeJSON(t, resp, &emails) - assert.EqualValues(t, []*api.Email{ + assert.Equal(t, []*api.Email{ { Email: "user2@example.com", Verified: true, @@ -119,7 +119,7 @@ func TestAPIDeleteEmail(t *testing.T) { var emails []*api.Email DecodeJSON(t, resp, &emails) - assert.EqualValues(t, []*api.Email{ + assert.Equal(t, []*api.Email{ { Email: "user2@example.com", Verified: true, diff --git a/tests/integration/api_user_follow_test.go b/tests/integration/api_user_follow_test.go index fe20af6769..6cb31a6802 100644 --- a/tests/integration/api_user_follow_test.go +++ b/tests/integration/api_user_follow_test.go @@ -32,7 +32,7 @@ func TestAPIFollow(t *testing.T) { t.Run("Follow", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/following/%s", user1)). + req := NewRequest(t, "PUT", "/api/v1/user/following/"+user1). AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) @@ -110,11 +110,11 @@ func TestAPIFollow(t *testing.T) { t.Run("CheckMyFollowing", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s", user1)). + req := NewRequest(t, "GET", "/api/v1/user/following/"+user1). AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/following/%s", user2)). + req = NewRequest(t, "GET", "/api/v1/user/following/"+user2). AddTokenAuth(token1) MakeRequest(t, req, http.StatusNotFound) }) @@ -122,7 +122,7 @@ func TestAPIFollow(t *testing.T) { t.Run("Unfollow", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/following/%s", user1)). + req := NewRequest(t, "DELETE", "/api/v1/user/following/"+user1). AddTokenAuth(token2) MakeRequest(t, req, http.StatusNoContent) }) diff --git a/tests/integration/api_user_info_test.go b/tests/integration/api_user_info_test.go index 89f7266859..06353eabe0 100644 --- a/tests/integration/api_user_info_test.go +++ b/tests/integration/api_user_info_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "testing" @@ -31,7 +30,7 @@ func TestAPIUserInfo(t *testing.T) { t.Run("GetInfo", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", user2)). + req := NewRequest(t, "GET", "/api/v1/users/"+user2). AddTokenAuth(token) resp := MakeRequest(t, req, http.StatusOK) @@ -39,17 +38,17 @@ func TestAPIUserInfo(t *testing.T) { DecodeJSON(t, resp, &u) assert.Equal(t, user2, u.UserName) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", user2)) + req = NewRequest(t, "GET", "/api/v1/users/"+user2) MakeRequest(t, req, http.StatusNotFound) // test if the placaholder Mail is returned if a User is not logged in - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", org3.Name)) + req = NewRequest(t, "GET", "/api/v1/users/"+org3.Name) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &u) assert.Equal(t, org3.GetPlaceholderEmail(), u.Email) // Test if the correct Mail is returned if a User is logged in - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s", org3.Name)). + req = NewRequest(t, "GET", "/api/v1/users/"+org3.Name). AddTokenAuth(token) resp = MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &u) diff --git a/tests/integration/api_user_search_test.go b/tests/integration/api_user_search_test.go index 5604a14259..97264969eb 100644 --- a/tests/integration/api_user_search_test.go +++ b/tests/integration/api_user_search_test.go @@ -66,7 +66,7 @@ func TestAPIUserSearchNotLoggedIn(t *testing.T) { for _, user := range results.Data { assert.Contains(t, user.UserName, query) modelUser = unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: user.ID}) - assert.EqualValues(t, modelUser.GetPlaceholderEmail(), user.Email) + assert.Equal(t, modelUser.GetPlaceholderEmail(), user.Email) } } @@ -85,8 +85,8 @@ func TestAPIUserSearchSystemUsers(t *testing.T) { assert.NotEmpty(t, results.Data) if assert.Len(t, results.Data, 1) { user := results.Data[0] - assert.EqualValues(t, user.UserName, systemUser.Name) - assert.EqualValues(t, user.ID, systemUser.ID) + assert.Equal(t, user.UserName, systemUser.Name) + assert.Equal(t, user.ID, systemUser.ID) } }) } @@ -108,7 +108,7 @@ func TestAPIUserSearchAdminLoggedInUserHidden(t *testing.T) { for _, user := range results.Data { assert.Contains(t, user.UserName, query) assert.NotEmpty(t, user.Email) - assert.EqualValues(t, "private", user.Visibility) + assert.Equal(t, "private", user.Visibility) } } diff --git a/tests/integration/api_user_secrets_test.go b/tests/integration/api_user_secrets_test.go index 56bf30e804..10024ac090 100644 --- a/tests/integration/api_user_secrets_test.go +++ b/tests/integration/api_user_secrets_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "testing" @@ -55,7 +54,7 @@ func TestAPIUserSecrets(t *testing.T) { } for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/secrets/%s", c.Name), api.CreateOrUpdateSecretOption{ + req := NewRequestWithJSON(t, "PUT", "/api/v1/user/actions/secrets/"+c.Name, api.CreateOrUpdateSecretOption{ Data: "data", }).AddTokenAuth(token) MakeRequest(t, req, c.ExpectedStatus) @@ -64,7 +63,7 @@ func TestAPIUserSecrets(t *testing.T) { t.Run("Update", func(t *testing.T) { name := "update_secret" - url := fmt.Sprintf("/api/v1/user/actions/secrets/%s", name) + url := "/api/v1/user/actions/secrets/" + name req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", @@ -79,7 +78,7 @@ func TestAPIUserSecrets(t *testing.T) { t.Run("Delete", func(t *testing.T) { name := "delete_secret" - url := fmt.Sprintf("/api/v1/user/actions/secrets/%s", name) + url := "/api/v1/user/actions/secrets/" + name req := NewRequestWithJSON(t, "PUT", url, api.CreateOrUpdateSecretOption{ Data: "initial", diff --git a/tests/integration/api_user_star_test.go b/tests/integration/api_user_star_test.go index 368756528a..989e7ab1d1 100644 --- a/tests/integration/api_user_star_test.go +++ b/tests/integration/api_user_star_test.go @@ -32,13 +32,13 @@ func TestAPIStar(t *testing.T) { t.Run("Star", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "PUT", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) // blocked user can't star a repo user34 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 34}) - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req = NewRequest(t, "PUT", "/api/v1/user/starred/"+repo). AddTokenAuth(getUserToken(t, user34.Name, auth_model.AccessTokenScopeWriteRepository)) MakeRequest(t, req, http.StatusForbidden) }) @@ -76,11 +76,11 @@ func TestAPIStar(t *testing.T) { t.Run("IsStarring", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "GET", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo+"notexisting")). + req = NewRequest(t, "GET", "/api/v1/user/starred/"+repo+"notexisting"). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNotFound) }) @@ -88,7 +88,7 @@ func TestAPIStar(t *testing.T) { t.Run("Unstar", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "DELETE", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusNoContent) }) @@ -109,12 +109,12 @@ func TestAPIStarDisabled(t *testing.T) { t.Run("Star", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "PUT", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusForbidden) user34 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 34}) - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req = NewRequest(t, "PUT", "/api/v1/user/starred/"+repo). AddTokenAuth(getUserToken(t, user34.Name, auth_model.AccessTokenScopeWriteRepository)) MakeRequest(t, req, http.StatusForbidden) }) @@ -138,11 +138,11 @@ func TestAPIStarDisabled(t *testing.T) { t.Run("IsStarring", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "GET", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusForbidden) - req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/starred/%s", repo+"notexisting")). + req = NewRequest(t, "GET", "/api/v1/user/starred/"+repo+"notexisting"). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusForbidden) }) @@ -150,7 +150,7 @@ func TestAPIStarDisabled(t *testing.T) { t.Run("Unstar", func(t *testing.T) { defer tests.PrintCurrentTest(t)() - req := NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/starred/%s", repo)). + req := NewRequest(t, "DELETE", "/api/v1/user/starred/"+repo). AddTokenAuth(tokenWithUserScope) MakeRequest(t, req, http.StatusForbidden) }) diff --git a/tests/integration/api_user_variables_test.go b/tests/integration/api_user_variables_test.go index 9fd84ddf81..367b83e7d4 100644 --- a/tests/integration/api_user_variables_test.go +++ b/tests/integration/api_user_variables_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "testing" @@ -63,7 +62,7 @@ func TestAPIUserVariables(t *testing.T) { } for _, c := range cases { - req := NewRequestWithJSON(t, "POST", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.CreateVariableOption{ + req := NewRequestWithJSON(t, "POST", "/api/v1/user/actions/variables/"+c.Name, api.CreateVariableOption{ Value: "value", }).AddTokenAuth(token) MakeRequest(t, req, c.ExpectedStatus) @@ -72,7 +71,7 @@ func TestAPIUserVariables(t *testing.T) { t.Run("UpdateUserVariable", func(t *testing.T) { variableName := "test_update_var" - url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) + url := "/api/v1/user/actions/variables/" + variableName req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ Value: "initial_val", }).AddTokenAuth(token) @@ -118,7 +117,7 @@ func TestAPIUserVariables(t *testing.T) { } for _, c := range cases { - req := NewRequestWithJSON(t, "PUT", fmt.Sprintf("/api/v1/user/actions/variables/%s", c.Name), api.UpdateVariableOption{ + req := NewRequestWithJSON(t, "PUT", "/api/v1/user/actions/variables/"+c.Name, api.UpdateVariableOption{ Name: c.UpdateName, Value: "updated_val", }).AddTokenAuth(token) @@ -128,7 +127,7 @@ func TestAPIUserVariables(t *testing.T) { t.Run("DeleteRepoVariable", func(t *testing.T) { variableName := "test_delete_var" - url := fmt.Sprintf("/api/v1/user/actions/variables/%s", variableName) + url := "/api/v1/user/actions/variables/" + variableName req := NewRequestWithJSON(t, "POST", url, api.CreateVariableOption{ Value: "initial_val", diff --git a/tests/integration/db_collation_test.go b/tests/integration/db_collation_test.go index acec4aa5d1..339bfce71c 100644 --- a/tests/integration/db_collation_test.go +++ b/tests/integration/db_collation_test.go @@ -75,7 +75,7 @@ func TestDatabaseCollation(t *testing.T) { defer test.MockVariableValue(&setting.Database.CharsetCollation, "utf8mb4_bin")() r, err := db.CheckCollations(x) assert.NoError(t, err) - assert.EqualValues(t, "utf8mb4_bin", r.ExpectedCollation) + assert.Equal(t, "utf8mb4_bin", r.ExpectedCollation) assert.NoError(t, db.ConvertDatabaseTable()) r, err = db.CheckCollations(x) assert.NoError(t, err) diff --git a/tests/integration/delete_user_test.go b/tests/integration/delete_user_test.go index ad3c882882..4b02c4725a 100644 --- a/tests/integration/delete_user_test.go +++ b/tests/integration/delete_user_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "testing" @@ -34,7 +33,7 @@ func TestUserDeleteAccount(t *testing.T) { session := loginUser(t, "user8") csrf := GetUserCSRFToken(t, session) - urlStr := fmt.Sprintf("/user/settings/account/delete?password=%s", userPassword) + urlStr := "/user/settings/account/delete?password=" + userPassword req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "_csrf": csrf, }) @@ -49,7 +48,7 @@ func TestUserDeleteAccountStillOwnRepos(t *testing.T) { session := loginUser(t, "user2") csrf := GetUserCSRFToken(t, session) - urlStr := fmt.Sprintf("/user/settings/account/delete?password=%s", userPassword) + urlStr := "/user/settings/account/delete?password=" + userPassword req := NewRequestWithValues(t, "POST", urlStr, map[string]string{ "_csrf": csrf, }) diff --git a/tests/integration/dump_restore_test.go b/tests/integration/dump_restore_test.go index 54683becaa..d2d43075c3 100644 --- a/tests/integration/dump_restore_test.go +++ b/tests/integration/dump_restore_test.go @@ -178,7 +178,7 @@ func (c *compareDump) assertEquals(repoBefore, repoAfter *repo_model.Repository) }).([]*base.Comment) assert.True(c.t, ok) for _, comment := range comments { - assert.EqualValues(c.t, issue.Number, comment.IssueIndex) + assert.Equal(c.t, issue.Number, comment.IssueIndex) } } @@ -205,7 +205,7 @@ func (c *compareDump) assertEquals(repoBefore, repoAfter *repo_model.Repository) comments, ok := c.assertEqual(filename, []base.Comment{}, compareFields{}).([]*base.Comment) assert.True(c.t, ok) for _, comment := range comments { - assert.EqualValues(c.t, pr.Number, comment.IssueIndex) + assert.Equal(c.t, pr.Number, comment.IssueIndex) } } } @@ -213,7 +213,7 @@ func (c *compareDump) assertEquals(repoBefore, repoAfter *repo_model.Repository) func (c *compareDump) assertLoadYAMLFiles(beforeFilename, afterFilename string, before, after any) { _, beforeErr := os.Stat(beforeFilename) _, afterErr := os.Stat(afterFilename) - assert.EqualValues(c.t, errors.Is(beforeErr, os.ErrNotExist), errors.Is(afterErr, os.ErrNotExist)) + assert.Equal(c.t, errors.Is(beforeErr, os.ErrNotExist), errors.Is(afterErr, os.ErrNotExist)) if errors.Is(beforeErr, os.ErrNotExist) { return } @@ -265,7 +265,7 @@ func (c *compareDump) assertEqual(filename string, kind any, fields compareField } func (c *compareDump) assertEqualSlices(before, after reflect.Value, fields compareFields) any { - assert.EqualValues(c.t, before.Len(), after.Len()) + assert.Equal(c.t, before.Len(), after.Len()) if before.Len() == after.Len() { for i := 0; i < before.Len(); i++ { _ = c.assertEqualValues( @@ -298,15 +298,15 @@ func (c *compareDump) assertEqualValues(before, after reflect.Value, fields comp assert.True(c.t, ok) as, ok := ai.(string) assert.True(c.t, ok) - assert.EqualValues(c.t, compare.transform(bs), compare.transform(as)) + assert.Equal(c.t, compare.transform(bs), compare.transform(as)) continue } if compare.before != nil && compare.after != nil { // // The fields are expected to have different values // - assert.EqualValues(c.t, compare.before, bi) - assert.EqualValues(c.t, compare.after, ai) + assert.Equal(c.t, compare.before, bi) + assert.Equal(c.t, compare.after, ai) continue } if compare.nested != nil { @@ -317,7 +317,7 @@ func (c *compareDump) assertEqualValues(before, after reflect.Value, fields comp continue } } - assert.EqualValues(c.t, bi, ai) + assert.Equal(c.t, bi, ai) } return after.Interface() } diff --git a/tests/integration/editor_test.go b/tests/integration/editor_test.go index fa58b8df42..a5936d86de 100644 --- a/tests/integration/editor_test.go +++ b/tests/integration/editor_test.go @@ -12,6 +12,7 @@ import ( "net/http/httptest" "net/url" "path" + "strings" "testing" repo_model "code.gitea.io/gitea/models/repo" @@ -68,7 +69,7 @@ func TestCreateFileOnProtectedBranch(t *testing.T) { session.MakeRequest(t, req, http.StatusSeeOther) // Check if master branch has been locked successfully flashMsg := session.GetCookieFlashMessage() - assert.EqualValues(t, `Branch protection for rule "master" has been updated.`, flashMsg.SuccessMsg) + assert.Equal(t, `Branch protection for rule "master" has been updated.`, flashMsg.SuccessMsg) // Request editor page req = NewRequest(t, "GET", "/user2/repo1/_new/master/") @@ -103,11 +104,11 @@ func TestCreateFileOnProtectedBranch(t *testing.T) { res := make(map[string]string) assert.NoError(t, json.NewDecoder(resp.Body).Decode(&res)) - assert.EqualValues(t, "/user2/repo1/settings/branches", res["redirect"]) + assert.Equal(t, "/user2/repo1/settings/branches", res["redirect"]) // Check if master branch has been locked successfully flashMsg = session.GetCookieFlashMessage() - assert.EqualValues(t, `Removing branch protection rule "1" failed.`, flashMsg.ErrorMsg) + assert.Equal(t, `Removing branch protection rule "1" failed.`, flashMsg.ErrorMsg) }) } @@ -135,7 +136,7 @@ func testEditFile(t *testing.T, session *TestSession, user, repo, branch, filePa // Verify the change req = NewRequest(t, "GET", path.Join(user, repo, "raw/branch", branch, filePath)) resp = session.MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, newContent, resp.Body.String()) + assert.Equal(t, newContent, resp.Body.String()) return resp } @@ -165,7 +166,7 @@ func testEditFileToNewBranch(t *testing.T, session *TestSession, user, repo, bra // Verify the change req = NewRequest(t, "GET", path.Join(user, repo, "raw/branch", targetBranch, filePath)) resp = session.MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, newContent, resp.Body.String()) + assert.Equal(t, newContent, resp.Body.String()) return resp } @@ -215,10 +216,10 @@ func TestWebGitCommitEmail(t *testing.T) { assert.Contains(t, errMsg, translation.NewLocale("en-US").Tr("repo.editor.invalid_commit_email")) } else { require.NotEqual(t, lastCommit.ID.String(), newCommit.ID.String()) - assert.EqualValues(t, expectedUserName, newCommit.Author.Name) - assert.EqualValues(t, expectedEmail, newCommit.Author.Email) - assert.EqualValues(t, expectedUserName, newCommit.Committer.Name) - assert.EqualValues(t, expectedEmail, newCommit.Committer.Email) + assert.Equal(t, expectedUserName, newCommit.Author.Name) + assert.Equal(t, expectedEmail, newCommit.Author.Email) + assert.Equal(t, expectedUserName, newCommit.Committer.Name) + assert.Equal(t, expectedEmail, newCommit.Committer.Email) } return resp } @@ -227,7 +228,7 @@ func TestWebGitCommitEmail(t *testing.T) { body := &bytes.Buffer{} uploadForm := multipart.NewWriter(body) file, _ := uploadForm.CreateFormFile("file", name) - _, _ = io.Copy(file, bytes.NewBufferString(content)) + _, _ = io.Copy(file, strings.NewReader(content)) _ = uploadForm.WriteField("_csrf", GetUserCSRFToken(t, session)) _ = uploadForm.Close() @@ -254,7 +255,7 @@ func TestWebGitCommitEmail(t *testing.T) { t.Run("EmailInvalid", func(t *testing.T) { defer tests.PrintCurrentTest(t)() email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{ID: 1, IsActivated: true}) - require.NotEqualValues(t, email.UID, user.ID) + require.NotEqual(t, email.UID, user.ID) makeReq(t, "/user2/repo1/_edit/master/README.md", map[string]string{ "tree_path": "README.md", "content": "test content", @@ -332,7 +333,7 @@ index 0000000000..bbbbbbbbbb ) // By the way, test the "cherrypick" page: a successful revert redirects to the main branch - assert.EqualValues(t, "/user2/repo1/src/branch/master", resp1.Header().Get("Location")) + assert.Equal(t, "/user2/repo1/src/branch/master", resp1.Header().Get("Location")) }) }) } diff --git a/tests/integration/empty_repo_test.go b/tests/integration/empty_repo_test.go index e122531dc9..f85d883cc7 100644 --- a/tests/integration/empty_repo_test.go +++ b/tests/integration/empty_repo_test.go @@ -11,6 +11,7 @@ import ( "mime/multipart" "net/http" "net/http/httptest" + "strings" "testing" auth_model "code.gitea.io/gitea/models/auth" @@ -130,7 +131,7 @@ func TestEmptyRepoUploadFile(t *testing.T) { mpForm := multipart.NewWriter(body) _ = mpForm.WriteField("_csrf", GetUserCSRFToken(t, session)) file, _ := mpForm.CreateFormFile("file", "uploaded-file.txt") - _, _ = io.Copy(file, bytes.NewBufferString("newly-uploaded-test-file")) + _, _ = io.Copy(file, strings.NewReader("newly-uploaded-test-file")) _ = mpForm.Close() req = NewRequestWithBody(t, "POST", "/user30/empty/upload-file", body) @@ -172,7 +173,7 @@ func TestEmptyRepoAddFileByAPI(t *testing.T) { var fileResponse api.FileResponse DecodeJSON(t, resp, &fileResponse) expectedHTMLURL := setting.AppURL + "user30/empty/src/branch/new_branch/new-file.txt" - assert.EqualValues(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) + assert.Equal(t, expectedHTMLURL, *fileResponse.Content.HTMLURL) req = NewRequest(t, "GET", "/user30/empty/src/branch/new_branch/new-file.txt") resp = session.MakeRequest(t, req, http.StatusOK) diff --git a/tests/integration/feed_repo_test.go b/tests/integration/feed_repo_test.go index 132ed32ced..2915b9b3f4 100644 --- a/tests/integration/feed_repo_test.go +++ b/tests/integration/feed_repo_test.go @@ -29,7 +29,7 @@ func TestFeedRepo(t *testing.T) { assert.Contains(t, rss.Channel.Link, "/user2/repo1") assert.NotEmpty(t, rss.Channel.PubDate) assert.Len(t, rss.Channel.Items, 1) - assert.EqualValues(t, "issue5", rss.Channel.Items[0].Description) + assert.Equal(t, "issue5", rss.Channel.Items[0].Description) assert.NotEmpty(t, rss.Channel.Items[0].PubDate) }) } diff --git a/tests/integration/git_general_test.go b/tests/integration/git_general_test.go index 95ffe20c35..34fe212d50 100644 --- a/tests/integration/git_general_test.go +++ b/tests/integration/git_general_test.go @@ -483,7 +483,7 @@ func doProtectBranch(ctx APITestContext, branch, userToWhitelistPush, userToWhit // Check if master branch has been locked successfully flashMsg := ctx.Session.GetCookieFlashMessage() - assert.EqualValues(t, `Branch protection for rule "`+branch+`" has been updated.`, flashMsg.SuccessMsg) + assert.Equal(t, `Branch protection for rule "`+branch+`" has been updated.`, flashMsg.SuccessMsg) } } @@ -592,7 +592,7 @@ func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) { defer tests.PrintCurrentTest(t)() // create a context for a currently non-existent repository - ctx.Reponame = fmt.Sprintf("repo-tmp-push-create-%s", u.Scheme) + ctx.Reponame = "repo-tmp-push-create-" + u.Scheme u.Path = ctx.GitPath() // Create a temporary directory @@ -623,7 +623,7 @@ func doPushCreate(ctx APITestContext, u *url.URL) func(t *testing.T) { // Now add a remote that is invalid to "Push To Create" invalidCtx := ctx - invalidCtx.Reponame = fmt.Sprintf("invalid/repo-tmp-push-create-%s", u.Scheme) + invalidCtx.Reponame = "invalid/repo-tmp-push-create-" + u.Scheme u.Path = invalidCtx.GitPath() t.Run("AddInvalidRemote", doGitAddRemote(tmpDir, "invalid", u)) diff --git a/tests/integration/git_helper_for_declarative_test.go b/tests/integration/git_helper_for_declarative_test.go index fce9b8f247..7d42508bfe 100644 --- a/tests/integration/git_helper_for_declarative_test.go +++ b/tests/integration/git_helper_for_declarative_test.go @@ -123,7 +123,7 @@ func doGitInitTestRepository(dstPath string) func(*testing.T) { // forcibly set default branch to master _, _, err := git.NewCommand("symbolic-ref", "HEAD", git.BranchPrefix+"master").RunStdString(git.DefaultContext, &git.RunOpts{Dir: dstPath}) assert.NoError(t, err) - assert.NoError(t, os.WriteFile(filepath.Join(dstPath, "README.md"), []byte(fmt.Sprintf("# Testing Repository\n\nOriginally created in: %s", dstPath)), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(dstPath, "README.md"), []byte("# Testing Repository\n\nOriginally created in: "+dstPath), 0o644)) assert.NoError(t, git.AddChanges(dstPath, true)) signature := git.Signature{ Email: "test@example.com", @@ -163,7 +163,7 @@ func doGitAddSomeCommits(dstPath, branch string) func(*testing.T) { return func(t *testing.T) { doGitCheckoutBranch(dstPath, branch)(t) - assert.NoError(t, os.WriteFile(filepath.Join(dstPath, fmt.Sprintf("file-%s.txt", branch)), []byte(fmt.Sprintf("file %s", branch)), 0o644)) + assert.NoError(t, os.WriteFile(filepath.Join(dstPath, fmt.Sprintf("file-%s.txt", branch)), []byte("file "+branch), 0o644)) assert.NoError(t, git.AddChanges(dstPath, true)) signature := git.Signature{ Email: "test@test.test", @@ -172,7 +172,7 @@ func doGitAddSomeCommits(dstPath, branch string) func(*testing.T) { assert.NoError(t, git.CommitChanges(dstPath, git.CommitChangesOptions{ Committer: &signature, Author: &signature, - Message: fmt.Sprintf("update %s", branch), + Message: "update " + branch, })) } } diff --git a/tests/integration/git_push_test.go b/tests/integration/git_push_test.go index ee4f203dbe..bac7b4f48b 100644 --- a/tests/integration/git_push_test.go +++ b/tests/integration/git_push_test.go @@ -170,7 +170,7 @@ func runTestGitPush(t *testing.T, u *url.URL, gitOperation func(t *testing.T, gi dbBranches := make([]*git_model.Branch, 0) require.NoError(t, db.GetEngine(db.DefaultContext).Where("repo_id=?", repo.ID).Find(&dbBranches)) - assert.Equalf(t, len(pushedBranches), len(dbBranches), "mismatched number of branches in db") + assert.Lenf(t, dbBranches, len(pushedBranches), "mismatched number of branches in db") dbBranchesMap := make(map[string]*git_model.Branch, len(dbBranches)) for _, branch := range dbBranches { dbBranchesMap[branch.Name] = branch diff --git a/tests/integration/git_smart_http_test.go b/tests/integration/git_smart_http_test.go index 1cbda5a673..e984fd3aad 100644 --- a/tests/integration/git_smart_http_test.go +++ b/tests/integration/git_smart_http_test.go @@ -72,7 +72,7 @@ func testGitSmartHTTP(t *testing.T, u *url.URL) { resp, err := http.DefaultClient.Do(req) require.NoError(t, err) defer resp.Body.Close() - assert.EqualValues(t, kase.code, resp.StatusCode) + assert.Equal(t, kase.code, resp.StatusCode) _, err = io.ReadAll(resp.Body) require.NoError(t, err) }) @@ -80,7 +80,7 @@ func testGitSmartHTTP(t *testing.T, u *url.URL) { } func testRenamedRepoRedirect(t *testing.T) { - defer test.MockVariableValue(&setting.Service.RequireSignInView, true)() + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() // git client requires to get a 301 redirect response before 401 unauthorized response req := NewRequest(t, "GET", "/user2/oldrepo1/info/refs") diff --git a/tests/integration/gpg_git_test.go b/tests/integration/gpg_git_test.go index 31695fb2e1..32de200f63 100644 --- a/tests/integration/gpg_git_test.go +++ b/tests/integration/gpg_git_test.go @@ -99,26 +99,14 @@ func TestGPGGit(t *testing.T) { testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) t.Run("CreateCRUDFile-Always", crudActionCreateFile( t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { - assert.NotNil(t, response.Verification) - if response.Verification == nil { - assert.FailNow(t, "no verification provided with response! %v", response) - } - assert.True(t, response.Verification.Verified) - if !response.Verification.Verified { - t.FailNow() - } + require.NotNil(t, response.Verification, "no verification provided with response! %v", response) + require.True(t, response.Verification.Verified) assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) })) t.Run("CreateCRUDFile-ParentSigned-always", crudActionCreateFile( t, testCtx, user, "parentsigned", "parentsigned-always", "signed-parent2.txt", func(t *testing.T, response api.FileResponse) { - assert.NotNil(t, response.Verification) - if response.Verification == nil { - assert.FailNow(t, "no verification provided with response! %v", response) - } - assert.True(t, response.Verification.Verified) - if !response.Verification.Verified { - t.FailNow() - } + require.NotNil(t, response.Verification, "no verification provided with response! %v", response) + require.True(t, response.Verification.Verified) assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) })) }) @@ -129,14 +117,8 @@ func TestGPGGit(t *testing.T) { testCtx := NewAPITestContext(t, username, "initial-unsigned", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) t.Run("CreateCRUDFile-Always-ParentSigned", crudActionCreateFile( t, testCtx, user, "always", "always-parentsigned", "signed-always-parentsigned.txt", func(t *testing.T, response api.FileResponse) { - assert.NotNil(t, response.Verification) - if response.Verification == nil { - assert.FailNow(t, "no verification provided with response! %v", response) - } - assert.True(t, response.Verification.Verified) - if !response.Verification.Verified { - t.FailNow() - } + require.NotNil(t, response.Verification, "no verification provided with response! %v", response) + require.True(t, response.Verification.Verified) assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) })) }) @@ -147,18 +129,9 @@ func TestGPGGit(t *testing.T) { testCtx := NewAPITestContext(t, username, "initial-always", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) t.Run("CheckMasterBranchSigned", doAPIGetBranch(testCtx, "master", func(t *testing.T, branch api.Branch) { - assert.NotNil(t, branch.Commit) - if branch.Commit == nil { - assert.FailNow(t, "no commit provided with branch! %v", branch) - } - assert.NotNil(t, branch.Commit.Verification) - if branch.Commit.Verification == nil { - assert.FailNow(t, "no verification provided with branch commit! %v", branch.Commit) - } - assert.True(t, branch.Commit.Verification.Verified) - if !branch.Commit.Verification.Verified { - t.FailNow() - } + require.NotNil(t, branch.Commit, "no commit provided with branch! %v", branch) + require.NotNil(t, branch.Commit.Verification, "no verification provided with branch commit! %v", branch.Commit) + require.True(t, branch.Commit.Verification.Verified) assert.Equal(t, "gitea@fake.local", branch.Commit.Verification.Signer.Email) })) }) @@ -181,11 +154,7 @@ func TestGPGGit(t *testing.T) { t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) t.Run("CreateCRUDFile-ParentSigned", crudActionCreateFile( t, testCtx, user, "master", "parentsigned", "signed-parent.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - if !response.Verification.Verified { - t.FailNow() - return - } + require.True(t, response.Verification.Verified) assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) })) }) @@ -197,11 +166,7 @@ func TestGPGGit(t *testing.T) { t.Run("CreateRepository", doAPICreateRepository(testCtx, false)) t.Run("CreateCRUDFile-Always", crudActionCreateFile( t, testCtx, user, "master", "always", "signed-always.txt", func(t *testing.T, response api.FileResponse) { - assert.True(t, response.Verification.Verified) - if !response.Verification.Verified { - t.FailNow() - return - } + require.True(t, response.Verification.Verified) assert.Equal(t, "gitea@fake.local", response.Verification.Signer.Email) })) }) @@ -273,7 +238,7 @@ func crudActionCreateFile(_ *testing.T, ctx APITestContext, user *user_model.Use Email: user.Email, }, }, - ContentBase64: base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("This is new text for %s", path))), + ContentBase64: base64.StdEncoding.EncodeToString([]byte("This is new text for " + path)), }, callback...) } diff --git a/tests/integration/incoming_email_test.go b/tests/integration/incoming_email_test.go index e968a2956e..6ccf82a9eb 100644 --- a/tests/integration/incoming_email_test.go +++ b/tests/integration/incoming_email_test.go @@ -50,12 +50,12 @@ func TestIncomingEmail(t *testing.T) { ref, err := incoming_payload.GetReferenceFromPayload(db.DefaultContext, issuePayload) assert.NoError(t, err) assert.IsType(t, ref, new(issues_model.Issue)) - assert.EqualValues(t, issue.ID, ref.(*issues_model.Issue).ID) + assert.Equal(t, issue.ID, ref.(*issues_model.Issue).ID) ref, err = incoming_payload.GetReferenceFromPayload(db.DefaultContext, commentPayload) assert.NoError(t, err) assert.IsType(t, ref, new(issues_model.Comment)) - assert.EqualValues(t, comment.ID, ref.(*issues_model.Comment).ID) + assert.Equal(t, comment.ID, ref.(*issues_model.Comment).ID) }) t.Run("Token", func(t *testing.T) { diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go index 2f6b7eae31..d5b7bb7a3e 100644 --- a/tests/integration/integration_test.go +++ b/tests/integration/integration_test.go @@ -310,7 +310,7 @@ func NewRequestWithValues(t testing.TB, method, urlStr string, values map[string func NewRequestWithURLValues(t testing.TB, method, urlStr string, urlValues url.Values) *RequestWrapper { t.Helper() - return NewRequestWithBody(t, method, urlStr, bytes.NewBufferString(urlValues.Encode())). + return NewRequestWithBody(t, method, urlStr, strings.NewReader(urlValues.Encode())). SetHeader("Content-Type", "application/x-www-form-urlencoded") } @@ -360,7 +360,7 @@ func MakeRequestNilResponseRecorder(t testing.TB, rw *RequestWrapper, expectedSt recorder := NewNilResponseRecorder() testWebRoutes.ServeHTTP(recorder, req) if expectedStatus != NoExpectedStatus { - if !assert.EqualValues(t, expectedStatus, recorder.Code, + if !assert.Equal(t, expectedStatus, recorder.Code, "Request: %s %s", req.Method, req.URL.String()) { logUnexpectedResponse(t, &recorder.ResponseRecorder) } @@ -374,7 +374,7 @@ func MakeRequestNilResponseHashSumRecorder(t testing.TB, rw *RequestWrapper, exp recorder := NewNilResponseHashSumRecorder() testWebRoutes.ServeHTTP(recorder, req) if expectedStatus != NoExpectedStatus { - if !assert.EqualValues(t, expectedStatus, recorder.Code, + if !assert.Equal(t, expectedStatus, recorder.Code, "Request: %s %s", req.Method, req.URL.String()) { logUnexpectedResponse(t, &recorder.ResponseRecorder) } diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go index dc0c9b1350..f0a5e4f519 100644 --- a/tests/integration/issue_test.go +++ b/tests/integration/issue_test.go @@ -32,7 +32,7 @@ import ( func getIssuesSelection(t testing.TB, htmlDoc *HTMLDoc) *goquery.Selection { issueList := htmlDoc.doc.Find("#issue-list") - assert.EqualValues(t, 1, issueList.Length()) + assert.Equal(t, 1, issueList.Length()) return issueList.Find(".flex-item").Find(".issue-title") } @@ -84,11 +84,11 @@ func TestViewIssuesSortByType(t *testing.T) { if expectedNumIssues > setting.UI.IssuePagingNum { expectedNumIssues = setting.UI.IssuePagingNum } - assert.EqualValues(t, expectedNumIssues, issuesSelection.Length()) + assert.Equal(t, expectedNumIssues, issuesSelection.Length()) issuesSelection.Each(func(_ int, selection *goquery.Selection) { issue := getIssue(t, repo.ID, selection) - assert.EqualValues(t, user.ID, issue.PosterID) + assert.Equal(t, user.ID, issue.PosterID) }) } @@ -108,7 +108,7 @@ func TestViewIssuesKeyword(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) issuesSelection := getIssuesSelection(t, htmlDoc) - assert.EqualValues(t, 1, issuesSelection.Length()) + assert.Equal(t, 1, issuesSelection.Length()) issuesSelection.Each(func(_ int, selection *goquery.Selection) { issue := getIssue(t, repo.ID, selection) assert.False(t, issue.IsClosed) @@ -195,21 +195,21 @@ func TestEditIssue(t *testing.T) { session := loginUser(t, "user2") issueURL := testNewIssue(t, session, "user2", "repo1", "Title", "Description") - req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/content", issueURL), map[string]string{ + req := NewRequestWithValues(t, "POST", issueURL+"/content", map[string]string{ "_csrf": GetUserCSRFToken(t, session), "content": "modified content", "context": fmt.Sprintf("/%s/%s", "user2", "repo1"), }) session.MakeRequest(t, req, http.StatusOK) - req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/content", issueURL), map[string]string{ + req = NewRequestWithValues(t, "POST", issueURL+"/content", map[string]string{ "_csrf": GetUserCSRFToken(t, session), "content": "modified content", "context": fmt.Sprintf("/%s/%s", "user2", "repo1"), }) session.MakeRequest(t, req, http.StatusBadRequest) - req = NewRequestWithValues(t, "POST", fmt.Sprintf("%s/content", issueURL), map[string]string{ + req = NewRequestWithValues(t, "POST", issueURL+"/content", map[string]string{ "_csrf": GetUserCSRFToken(t, session), "content": "modified content", "content_version": "1", @@ -510,7 +510,7 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 20) query.Add("limit", "5") @@ -518,7 +518,7 @@ func TestSearchIssues(t *testing.T) { req = NewRequest(t, "GET", link.String()) resp = session.MakeRequest(t, req, http.StatusOK) DecodeJSON(t, resp, &apiIssues) - assert.EqualValues(t, "22", resp.Header().Get("X-Total-Count")) + assert.Equal(t, "22", resp.Header().Get("X-Total-Count")) assert.Len(t, apiIssues, 5) query = url.Values{"assigned": {"true"}, "state": {"all"}} @@ -645,7 +645,7 @@ func TestGetIssueInfo(t *testing.T) { } DecodeJSON(t, resp, &respStruct) - assert.EqualValues(t, issue.ID, respStruct.ConvertedIssue.ID) + assert.Equal(t, issue.ID, respStruct.ConvertedIssue.ID) assert.Contains(t, string(respStruct.RenderedLabels), `"labels-list"`) } @@ -665,7 +665,7 @@ func TestUpdateIssueDeadline(t *testing.T) { req := NewRequestWithValues(t, "POST", urlStr, map[string]string{"deadline": "2022-04-06"}) session.MakeRequest(t, req, http.StatusOK) issueAfter := unittest.AssertExistsAndLoadBean(t, &issues_model.Issue{ID: 10}) - assert.EqualValues(t, "2022-04-06", issueAfter.DeadlineUnix.FormatDate()) + assert.Equal(t, "2022-04-06", issueAfter.DeadlineUnix.FormatDate()) req = NewRequestWithValues(t, "POST", urlStr, map[string]string{"deadline": ""}) session.MakeRequest(t, req, http.StatusOK) @@ -686,8 +686,8 @@ func TestIssueReferenceURL(t *testing.T) { // the "reference" uses relative URLs, then JS code will convert them to absolute URLs for current origin, in case users are using multiple domains ref, _ := htmlDoc.Find(`.timeline-item.comment.first .reference-issue`).Attr("data-reference") - assert.EqualValues(t, "/user2/repo1/issues/1#issue-1", ref) + assert.Equal(t, "/user2/repo1/issues/1#issue-1", ref) ref, _ = htmlDoc.Find(`.timeline-item.comment:not(.first) .reference-issue`).Attr("data-reference") - assert.EqualValues(t, "/user2/repo1/issues/1#issuecomment-2", ref) + assert.Equal(t, "/user2/repo1/issues/1#issuecomment-2", ref) } diff --git a/tests/integration/lfs_local_endpoint_test.go b/tests/integration/lfs_local_endpoint_test.go index d42888bbe1..e67f0712a3 100644 --- a/tests/integration/lfs_local_endpoint_test.go +++ b/tests/integration/lfs_local_endpoint_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/url" "os" "path/filepath" @@ -41,55 +40,55 @@ func TestDetermineLocalEndpoint(t *testing.T) { { cloneurl: root, lfsurl: "", - expected: str2url(fmt.Sprintf("file://%s", root)), + expected: str2url("file://" + root), }, // case 1 { cloneurl: root, lfsurl: lfsroot, - expected: str2url(fmt.Sprintf("file://%s", lfsroot)), + expected: str2url("file://" + lfsroot), }, // case 2 { cloneurl: "https://git.com/repo.git", lfsurl: lfsroot, - expected: str2url(fmt.Sprintf("file://%s", lfsroot)), + expected: str2url("file://" + lfsroot), }, // case 3 { cloneurl: rootdotgit, lfsurl: "", - expected: str2url(fmt.Sprintf("file://%s", filepath.Join(rootdotgit, ".git"))), + expected: str2url("file://" + filepath.Join(rootdotgit, ".git")), }, // case 4 { cloneurl: "", lfsurl: rootdotgit, - expected: str2url(fmt.Sprintf("file://%s", filepath.Join(rootdotgit, ".git"))), + expected: str2url("file://" + filepath.Join(rootdotgit, ".git")), }, // case 5 { cloneurl: rootdotgit, lfsurl: rootdotgit, - expected: str2url(fmt.Sprintf("file://%s", filepath.Join(rootdotgit, ".git"))), + expected: str2url("file://" + filepath.Join(rootdotgit, ".git")), }, // case 6 { - cloneurl: fmt.Sprintf("file://%s", root), + cloneurl: "file://" + root, lfsurl: "", - expected: str2url(fmt.Sprintf("file://%s", root)), + expected: str2url("file://" + root), }, // case 7 { - cloneurl: fmt.Sprintf("file://%s", root), - lfsurl: fmt.Sprintf("file://%s", lfsroot), - expected: str2url(fmt.Sprintf("file://%s", lfsroot)), + cloneurl: "file://" + root, + lfsurl: "file://" + lfsroot, + expected: str2url("file://" + lfsroot), }, // case 8 { cloneurl: root, - lfsurl: fmt.Sprintf("file://%s", lfsroot), - expected: str2url(fmt.Sprintf("file://%s", lfsroot)), + lfsurl: "file://" + lfsroot, + expected: str2url("file://" + lfsroot), }, // case 9 { diff --git a/tests/integration/links_test.go b/tests/integration/links_test.go index 6573a47ccc..ec59e147d2 100644 --- a/tests/integration/links_test.go +++ b/tests/integration/links_test.go @@ -54,6 +54,7 @@ func TestRedirectsNoLogin(t *testing.T) { {"/user2/repo1/src/master", "/user2/repo1/src/branch/master"}, {"/user2/repo1/src/master/a%2fb.txt", "/user2/repo1/src/branch/master/a%2fb.txt"}, {"/user2/repo1/src/master/directory/file.txt?a=1", "/user2/repo1/src/branch/master/directory/file.txt?a=1"}, + {"/user2/repo1/src/branch/master/directory/file.txt?raw=1&other=2", "/user2/repo1/raw/branch/master/directory/file.txt"}, {"/user2/repo1/tree/a%2fb?a=1", "/user2/repo1/src/a%2fb?a=1"}, {"/user2/repo1/blob/123456/%20?a=1", "/user2/repo1/src/commit/123456/%20?a=1"}, {"/user/avatar/GhosT/-1", "/assets/img/avatar_default.png"}, @@ -63,7 +64,7 @@ func TestRedirectsNoLogin(t *testing.T) { for _, c := range redirects { req := NewRequest(t, "GET", c.from) resp := MakeRequest(t, req, http.StatusSeeOther) - assert.EqualValues(t, path.Join(setting.AppSubURL, c.to), test.RedirectURL(resp)) + assert.Equal(t, path.Join(setting.AppSubURL, c.to), test.RedirectURL(resp)) } } diff --git a/tests/integration/markup_external_test.go b/tests/integration/markup_external_test.go index 2d713b0eb9..47d143a29e 100644 --- a/tests/integration/markup_external_test.go +++ b/tests/integration/markup_external_test.go @@ -27,7 +27,7 @@ func TestExternalMarkupRenderer(t *testing.T) { req := NewRequest(t, "GET", "/user30/renderer/src/branch/master/README.html") resp := MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) + assert.Equal(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) bs, err := io.ReadAll(resp.Body) assert.NoError(t, err) @@ -36,25 +36,25 @@ func TestExternalMarkupRenderer(t *testing.T) { div := doc.Find("div.file-view") data, err := div.Html() assert.NoError(t, err) - assert.EqualValues(t, "\n\ttest external renderer\n", strings.TrimSpace(data)) + assert.Equal(t, "\n\ttest external renderer\n", strings.TrimSpace(data)) r := markup.GetRendererByFileName("a.html").(*external.Renderer) r.RenderContentMode = setting.RenderContentModeIframe req = NewRequest(t, "GET", "/user30/renderer/src/branch/master/README.html") resp = MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) + assert.Equal(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) doc = NewHTMLParser(t, bytes.NewBuffer(bs)) iframe := doc.Find("iframe") - assert.EqualValues(t, "/user30/renderer/render/branch/master/README.html", iframe.AttrOr("src", "")) + assert.Equal(t, "/user30/renderer/render/branch/master/README.html", iframe.AttrOr("src", "")) req = NewRequest(t, "GET", "/user30/renderer/render/branch/master/README.html") resp = MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) + assert.Equal(t, "text/html; charset=utf-8", resp.Header().Get("Content-Type")) bs, err = io.ReadAll(resp.Body) assert.NoError(t, err) - assert.EqualValues(t, "frame-src 'self'; sandbox allow-scripts", resp.Header().Get("Content-Security-Policy")) - assert.EqualValues(t, "\n\ttest external renderer\n\n", string(bs)) + assert.Equal(t, "frame-src 'self'; sandbox allow-scripts", resp.Header().Get("Content-Security-Policy")) + assert.Equal(t, "\n\ttest external renderer\n\n", string(bs)) } diff --git a/tests/integration/migrate_test.go b/tests/integration/migrate_test.go index 59dd6907db..a89dc8b85c 100644 --- a/tests/integration/migrate_test.go +++ b/tests/integration/migrate_test.go @@ -9,6 +9,7 @@ import ( "net/url" "os" "path/filepath" + "strconv" "testing" auth_model "code.gitea.io/gitea/models/auth" @@ -84,7 +85,7 @@ func TestMigrateGiteaForm(t *testing.T) { assert.True(t, exists, "The template has changed") serviceInput, exists := form.Find(`input[name="service"]`).Attr("value") assert.True(t, exists) - assert.EqualValues(t, fmt.Sprintf("%d", structs.GiteaService), serviceInput) + assert.Equal(t, fmt.Sprintf("%d", structs.GiteaService), serviceInput) // Step 4: submit the migration to only migrate issues migratedRepoName := "otherrepo" req = NewRequestWithValues(t, "POST", link, map[string]string{ @@ -95,12 +96,12 @@ func TestMigrateGiteaForm(t *testing.T) { "issues": "on", "repo_name": migratedRepoName, "description": "", - "uid": fmt.Sprintf("%d", repoOwner.ID), + "uid": strconv.FormatInt(repoOwner.ID, 10), }) resp = session.MakeRequest(t, req, http.StatusSeeOther) // Step 5: a redirection displays the migrated repository loc := resp.Header().Get("Location") - assert.EqualValues(t, fmt.Sprintf("/%s/%s", ownerName, migratedRepoName), loc) + assert.Equal(t, fmt.Sprintf("/%s/%s", ownerName, migratedRepoName), loc) // Step 6: check the repo was created unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: migratedRepoName}) }) diff --git a/tests/integration/migration-test/migration_test.go b/tests/integration/migration-test/migration_test.go index c319fd20a7..ffb8afa9c5 100644 --- a/tests/integration/migration-test/migration_test.go +++ b/tests/integration/migration-test/migration_test.go @@ -140,10 +140,10 @@ func restoreOldDB(t *testing.T, version string) { assert.NoError(t, err) defer db.Close() - _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)) + _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name) assert.NoError(t, err) - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)) + _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name) assert.NoError(t, err) db.Close() @@ -170,10 +170,10 @@ func restoreOldDB(t *testing.T, version string) { } defer db.Close() - _, err = db.Exec(fmt.Sprintf("DROP DATABASE IF EXISTS %s", setting.Database.Name)) + _, err = db.Exec("DROP DATABASE IF EXISTS " + setting.Database.Name) assert.NoError(t, err) - _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)) + _, err = db.Exec("CREATE DATABASE " + setting.Database.Name) assert.NoError(t, err) db.Close() @@ -195,7 +195,7 @@ func restoreOldDB(t *testing.T, version string) { if !schrows.Next() { // Create and setup a DB schema - _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)) + _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema) assert.NoError(t, err) } schrows.Close() diff --git a/tests/integration/mirror_pull_test.go b/tests/integration/mirror_pull_test.go index 7ab8f72b4a..fdf399f2bc 100644 --- a/tests/integration/mirror_pull_test.go +++ b/tests/integration/mirror_pull_test.go @@ -99,7 +99,7 @@ func TestMirrorPull(t *testing.T) { count, err := db.Count[repo_model.Release](db.DefaultContext, findOptions) assert.NoError(t, err) - assert.EqualValues(t, initCount+1, count) + assert.Equal(t, initCount+1, count) release, err := repo_model.GetRelease(db.DefaultContext, repo.ID, "v0.2") assert.NoError(t, err) @@ -110,5 +110,5 @@ func TestMirrorPull(t *testing.T) { count, err = db.Count[repo_model.Release](db.DefaultContext, findOptions) assert.NoError(t, err) - assert.EqualValues(t, initCount, count) + assert.Equal(t, initCount, count) } diff --git a/tests/integration/mirror_push_test.go b/tests/integration/mirror_push_test.go index a8046cdc59..40d100cd27 100644 --- a/tests/integration/mirror_push_test.go +++ b/tests/integration/mirror_push_test.go @@ -128,18 +128,18 @@ func TestRepoSettingPushMirrorUpdate(t *testing.T) { pushMirrors, cnt, err := repo_model.GetPushMirrorsByRepoID(db.DefaultContext, repo2.ID, db.ListOptions{}) assert.NoError(t, err) assert.EqualValues(t, 1, cnt) - assert.EqualValues(t, 24*time.Hour, pushMirrors[0].Interval) + assert.Equal(t, 24*time.Hour, pushMirrors[0].Interval) repo2PushMirrorID := pushMirrors[0].ID // update repo2 push mirror assert.True(t, doUpdatePushMirror(t, session, "user2", "repo2", repo2PushMirrorID, "10m0s")) pushMirror := unittest.AssertExistsAndLoadBean(t, &repo_model.PushMirror{ID: repo2PushMirrorID}) - assert.EqualValues(t, 10*time.Minute, pushMirror.Interval) + assert.Equal(t, 10*time.Minute, pushMirror.Interval) // avoid updating repo2 push mirror from repo1 assert.False(t, doUpdatePushMirror(t, session, "user2", "repo1", repo2PushMirrorID, "20m0s")) pushMirror = unittest.AssertExistsAndLoadBean(t, &repo_model.PushMirror{ID: repo2PushMirrorID}) - assert.EqualValues(t, 10*time.Minute, pushMirror.Interval) // not changed + assert.Equal(t, 10*time.Minute, pushMirror.Interval) // not changed // avoid deleting repo2 push mirror from repo1 assert.False(t, doRemovePushMirror(t, session, "user2", "repo1", repo2PushMirrorID)) diff --git a/tests/integration/org_team_invite_test.go b/tests/integration/org_team_invite_test.go index 4c1053702e..7444980ea8 100644 --- a/tests/integration/org_team_invite_test.go +++ b/tests/integration/org_team_invite_test.go @@ -58,7 +58,7 @@ func TestOrgTeamEmailInvite(t *testing.T) { session = loginUser(t, user.Name) // join the team - inviteURL := fmt.Sprintf("/org/invite/%s", invites[0].Token) + inviteURL := "/org/invite/" + invites[0].Token csrf = GetUserCSRFToken(t, session) req = NewRequestWithValues(t, "POST", inviteURL, map[string]string{ "_csrf": csrf, @@ -108,8 +108,8 @@ func TestOrgTeamEmailInviteRedirectsExistingUser(t *testing.T) { assert.Len(t, invites, 1) // accept the invite - inviteURL := fmt.Sprintf("/org/invite/%s", invites[0].Token) - req = NewRequest(t, "GET", fmt.Sprintf("/user/login?redirect_to=%s", url.QueryEscape(inviteURL))) + inviteURL := "/org/invite/" + invites[0].Token + req = NewRequest(t, "GET", "/user/login?redirect_to="+url.QueryEscape(inviteURL)) resp = MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) @@ -179,8 +179,8 @@ func TestOrgTeamEmailInviteRedirectsNewUser(t *testing.T) { assert.Len(t, invites, 1) // accept the invite - inviteURL := fmt.Sprintf("/org/invite/%s", invites[0].Token) - req = NewRequest(t, "GET", fmt.Sprintf("/user/sign_up?redirect_to=%s", url.QueryEscape(inviteURL))) + inviteURL := "/org/invite/" + invites[0].Token + req = NewRequest(t, "GET", "/user/sign_up?redirect_to="+url.QueryEscape(inviteURL)) resp = MakeRequest(t, req, http.StatusOK) doc := NewHTMLParser(t, resp.Body) @@ -260,8 +260,8 @@ func TestOrgTeamEmailInviteRedirectsNewUserWithActivation(t *testing.T) { // new user: accept the invite session = emptyTestSession(t) - inviteURL := fmt.Sprintf("/org/invite/%s", invites[0].Token) - req = NewRequest(t, "GET", fmt.Sprintf("/user/sign_up?redirect_to=%s", url.QueryEscape(inviteURL))) + inviteURL := "/org/invite/" + invites[0].Token + req = NewRequest(t, "GET", "/user/sign_up?redirect_to="+url.QueryEscape(inviteURL)) session.MakeRequest(t, req, http.StatusOK) req = NewRequestWithValues(t, "POST", "/user/sign_up", map[string]string{ "user_name": "doesnotexist", @@ -275,7 +275,7 @@ func TestOrgTeamEmailInviteRedirectsNewUserWithActivation(t *testing.T) { assert.NoError(t, err) activationCode := user_model.GenerateUserTimeLimitCode(&user_model.TimeLimitCodeOptions{Purpose: user_model.TimeLimitCodeActivateAccount}, user) - activateURL := fmt.Sprintf("/user/activate?code=%s", activationCode) + activateURL := "/user/activate?code=" + activationCode req = NewRequestWithValues(t, "POST", activateURL, map[string]string{ "password": "examplePassword!1", }) @@ -337,8 +337,8 @@ func TestOrgTeamEmailInviteRedirectsExistingUserWithLogin(t *testing.T) { session = loginUser(t, "user5") // accept the invite (note: this uses the sign_up url) - inviteURL := fmt.Sprintf("/org/invite/%s", invites[0].Token) - req = NewRequest(t, "GET", fmt.Sprintf("/user/sign_up?redirect_to=%s", url.QueryEscape(inviteURL))) + inviteURL := "/org/invite/" + invites[0].Token + req = NewRequest(t, "GET", "/user/sign_up?redirect_to="+url.QueryEscape(inviteURL)) resp = session.MakeRequest(t, req, http.StatusSeeOther) assert.Equal(t, inviteURL, test.RedirectURL(resp)) diff --git a/tests/integration/org_test.go b/tests/integration/org_test.go index ef4ef2bb9b..b1376fe1bf 100644 --- a/tests/integration/org_test.go +++ b/tests/integration/org_test.go @@ -41,7 +41,7 @@ func TestOrgRepos(t *testing.T) { sel := htmlDoc.doc.Find("a.name") assert.Len(t, repos, len(sel.Nodes)) for i := 0; i < len(repos); i++ { - assert.EqualValues(t, repos[i], strings.TrimSpace(sel.Eq(i).Text())) + assert.Equal(t, repos[i], strings.TrimSpace(sel.Eq(i).Text())) } } }) @@ -151,7 +151,7 @@ func TestOrgRestrictedUser(t *testing.T) { // assert restrictedUser cannot see the org or the public repo restrictedSession := loginUser(t, restrictedUser) - req := NewRequest(t, "GET", fmt.Sprintf("/%s", orgName)) + req := NewRequest(t, "GET", "/"+orgName) restrictedSession.MakeRequest(t, req, http.StatusNotFound) req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s", orgName, repoName)) @@ -188,7 +188,7 @@ func TestOrgRestrictedUser(t *testing.T) { _ = adminSession.MakeRequest(t, req, http.StatusNoContent) // Now we need to check if the restrictedUser can access the repo - req = NewRequest(t, "GET", fmt.Sprintf("/%s", orgName)) + req = NewRequest(t, "GET", "/"+orgName) restrictedSession.MakeRequest(t, req, http.StatusOK) req = NewRequest(t, "GET", fmt.Sprintf("/%s/%s", orgName, repoName)) diff --git a/tests/integration/project_test.go b/tests/integration/project_test.go index 111356b1da..13213c254d 100644 --- a/tests/integration/project_test.go +++ b/tests/integration/project_test.go @@ -79,9 +79,9 @@ func TestMoveRepoProjectColumns(t *testing.T) { columnsAfter, err := project1.GetColumns(db.DefaultContext) assert.NoError(t, err) assert.Len(t, columnsAfter, 3) - assert.EqualValues(t, columns[1].ID, columnsAfter[0].ID) - assert.EqualValues(t, columns[2].ID, columnsAfter[1].ID) - assert.EqualValues(t, columns[0].ID, columnsAfter[2].ID) + assert.Equal(t, columns[1].ID, columnsAfter[0].ID) + assert.Equal(t, columns[2].ID, columnsAfter[1].ID) + assert.Equal(t, columns[0].ID, columnsAfter[2].ID) assert.NoError(t, project_model.DeleteProjectByID(db.DefaultContext, project1.ID)) } diff --git a/tests/integration/pull_compare_test.go b/tests/integration/pull_compare_test.go index 4ac5be18be..86bdd1b9e3 100644 --- a/tests/integration/pull_compare_test.go +++ b/tests/integration/pull_compare_test.go @@ -47,7 +47,7 @@ func TestPullCompare(t *testing.T) { assert.True(t, exists, "The template has changed") req = NewRequest(t, "GET", link) resp = session.MakeRequest(t, req, http.StatusOK) - assert.EqualValues(t, http.StatusOK, resp.Code) + assert.Equal(t, http.StatusOK, resp.Code) // test the edit button in the PR diff view req = NewRequest(t, "GET", "/user2/repo1/pulls/3/files") @@ -86,7 +86,7 @@ func TestPullCompare(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) doc = NewHTMLParser(t, resp.Body) editButtonCount = doc.doc.Find(".diff-file-header-actions a[href*='/_edit/']").Length() - assert.EqualValues(t, 0, editButtonCount, "Expected not to find a button to edit a file in the PR diff view because head repository has been deleted") + assert.Equal(t, 0, editButtonCount, "Expected not to find a button to edit a file in the PR diff view because head repository has been deleted") }) } @@ -110,7 +110,7 @@ func TestPullCompare_EnableAllowEditsFromMaintainer(t *testing.T) { // user2 (admin of repo3) goes to the PR files page user2Session := loginUser(t, "user2") - resp = user2Session.MakeRequest(t, NewRequest(t, "GET", fmt.Sprintf("%s/files", prURL)), http.StatusOK) + resp = user2Session.MakeRequest(t, NewRequest(t, "GET", prURL+"/files"), http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) nodes := htmlDoc.doc.Find(".diff-file-box[data-new-filename=\"README.md\"] .diff-file-header-actions .tippy-target a") if assert.Equal(t, 1, nodes.Length()) { @@ -127,14 +127,14 @@ func TestPullCompare_EnableAllowEditsFromMaintainer(t *testing.T) { htmlDoc = NewHTMLParser(t, resp.Body) dataURL, exists := htmlDoc.doc.Find("#allow-edits-from-maintainers").Attr("data-url") assert.True(t, exists) - req := NewRequestWithValues(t, "POST", fmt.Sprintf("%s/set_allow_maintainer_edit", dataURL), map[string]string{ + req := NewRequestWithValues(t, "POST", dataURL+"/set_allow_maintainer_edit", map[string]string{ "_csrf": htmlDoc.GetCSRF(), "allow_maintainer_edit": "true", }) user4Session.MakeRequest(t, req, http.StatusOK) // user2 (admin of repo3) goes to the PR files page again - resp = user2Session.MakeRequest(t, NewRequest(t, "GET", fmt.Sprintf("%s/files", prURL)), http.StatusOK) + resp = user2Session.MakeRequest(t, NewRequest(t, "GET", prURL+"/files"), http.StatusOK) htmlDoc = NewHTMLParser(t, resp.Body) nodes = htmlDoc.doc.Find(".diff-file-box[data-new-filename=\"README.md\"] .diff-file-header-actions .tippy-target a") if assert.Equal(t, 2, nodes.Length()) { diff --git a/tests/integration/pull_create_test.go b/tests/integration/pull_create_test.go index 461a1400f7..179c84e673 100644 --- a/tests/integration/pull_create_test.go +++ b/tests/integration/pull_create_test.go @@ -293,10 +293,10 @@ func TestCreatePullWhenBlocked(t *testing.T) { // sessionBase := loginUser(t, "user2") token := getUserToken(t, RepoOwner, auth_model.AccessTokenScopeWriteUser) - req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/blocks/%s", ForkOwner)). + req := NewRequest(t, "GET", "/api/v1/user/blocks/"+ForkOwner). AddTokenAuth(token) MakeRequest(t, req, http.StatusNotFound) - req = NewRequest(t, "PUT", fmt.Sprintf("/api/v1/user/blocks/%s", ForkOwner)). + req = NewRequest(t, "PUT", "/api/v1/user/blocks/"+ForkOwner). AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) @@ -308,7 +308,7 @@ func TestCreatePullWhenBlocked(t *testing.T) { // Teardown // Unblock user - req = NewRequest(t, "DELETE", fmt.Sprintf("/api/v1/user/blocks/%s", ForkOwner)). + req = NewRequest(t, "DELETE", "/api/v1/user/blocks/"+ForkOwner). AddTokenAuth(token) MakeRequest(t, req, http.StatusNoContent) }) diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go index 1c8318db0d..cf50d5e639 100644 --- a/tests/integration/pull_merge_test.go +++ b/tests/integration/pull_merge_test.go @@ -66,7 +66,7 @@ func testPullMerge(t *testing.T, session *TestSession, user, repo, pullnum strin }{} DecodeJSON(t, resp, &respJSON) - assert.EqualValues(t, fmt.Sprintf("/%s/%s/pulls/%s", user, repo, pullnum), respJSON.Redirect) + assert.Equal(t, fmt.Sprintf("/%s/%s/pulls/%s", user, repo, pullnum), respJSON.Redirect) return resp } @@ -100,7 +100,7 @@ func TestPullMerge(t *testing.T) { resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleMerge, false) hookTasks, err = webhook.HookTasks(db.DefaultContext, 1, 1) @@ -122,7 +122,7 @@ func TestPullRebase(t *testing.T) { resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleRebase, false) hookTasks, err = webhook.HookTasks(db.DefaultContext, 1, 1) @@ -144,7 +144,7 @@ func TestPullRebaseMerge(t *testing.T) { resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleRebaseMerge, false) hookTasks, err = webhook.HookTasks(db.DefaultContext, 1, 1) @@ -167,7 +167,7 @@ func TestPullSquash(t *testing.T) { resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleSquash, false) hookTasks, err = webhook.HookTasks(db.DefaultContext, 1, 1) @@ -185,7 +185,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) { resp := testPullCreate(t, session, "user1", "repo1", false, "master", "feature/test", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleMerge, false) // Check PR branch deletion @@ -198,7 +198,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) { assert.NotEmpty(t, respJSON.Redirect, "Redirected URL is not found") elem = strings.Split(respJSON.Redirect, "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) // Check branch deletion result req := NewRequest(t, "GET", respJSON.Redirect) @@ -207,7 +207,7 @@ func TestPullCleanUpAfterMerge(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) resultMsg := htmlDoc.doc.Find(".ui.message>p").Text() - assert.EqualValues(t, "Branch \"user1/repo1:feature/test\" has been deleted.", resultMsg) + assert.Equal(t, "Branch \"user1/repo1:feature/test\" has been deleted.", resultMsg) }) } @@ -296,7 +296,7 @@ func TestCantMergeUnrelated(t *testing.T) { err := git.NewCommand("read-tree", "--empty").Run(git.DefaultContext, &git.RunOpts{Dir: path}) assert.NoError(t, err) - stdin := bytes.NewBufferString("Unrelated File") + stdin := strings.NewReader("Unrelated File") var stdout strings.Builder err = git.NewCommand("hash-object", "-w", "--stdin").Run(git.DefaultContext, &git.RunOpts{ Dir: path, @@ -544,11 +544,11 @@ func TestPullRetargetChildOnBranchDelete(t *testing.T) { respBasePR := testPullCreate(t, session, "user2", "repo1", true, "master", "base-pr", "Base Pull Request") elemBasePR := strings.Split(test.RedirectURL(respBasePR), "/") - assert.EqualValues(t, "pulls", elemBasePR[3]) + assert.Equal(t, "pulls", elemBasePR[3]) respChildPR := testPullCreate(t, session, "user1", "repo1", false, "base-pr", "child-pr", "Child Pull Request") elemChildPR := strings.Split(test.RedirectURL(respChildPR), "/") - assert.EqualValues(t, "pulls", elemChildPR[3]) + assert.Equal(t, "pulls", elemChildPR[3]) testPullMerge(t, session, elemBasePR[1], elemBasePR[2], elemBasePR[4], repo_model.MergeStyleMerge, true) @@ -564,8 +564,8 @@ func TestPullRetargetChildOnBranchDelete(t *testing.T) { targetBranch := htmlDoc.doc.Find("#branch_target>a").Text() prStatus := strings.TrimSpace(htmlDoc.doc.Find(".issue-title-meta>.issue-state-label").Text()) - assert.EqualValues(t, "master", targetBranch) - assert.EqualValues(t, "Open", prStatus) + assert.Equal(t, "master", targetBranch) + assert.Equal(t, "Open", prStatus) }) } @@ -578,11 +578,11 @@ func TestPullDontRetargetChildOnWrongRepo(t *testing.T) { respBasePR := testPullCreate(t, session, "user1", "repo1", false, "master", "base-pr", "Base Pull Request") elemBasePR := strings.Split(test.RedirectURL(respBasePR), "/") - assert.EqualValues(t, "pulls", elemBasePR[3]) + assert.Equal(t, "pulls", elemBasePR[3]) respChildPR := testPullCreate(t, session, "user1", "repo1", true, "base-pr", "child-pr", "Child Pull Request") elemChildPR := strings.Split(test.RedirectURL(respChildPR), "/") - assert.EqualValues(t, "pulls", elemChildPR[3]) + assert.Equal(t, "pulls", elemChildPR[3]) defer test.MockVariableValue(&setting.Repository.PullRequest.RetargetChildrenOnMerge, false)() @@ -601,8 +601,8 @@ func TestPullDontRetargetChildOnWrongRepo(t *testing.T) { targetBranch := htmlDoc.doc.Find("#branch_target>span").Text() prStatus := strings.TrimSpace(htmlDoc.doc.Find(".issue-title-meta>.issue-state-label").Text()) - assert.EqualValues(t, "base-pr", targetBranch) - assert.EqualValues(t, "Closed", prStatus) + assert.Equal(t, "base-pr", targetBranch) + assert.Equal(t, "Closed", prStatus) }) } @@ -614,7 +614,7 @@ func TestPullRequestMergedWithNoPermissionDeleteBranch(t *testing.T) { respBasePR := testPullCreate(t, session, "user4", "repo1", false, "master", "base-pr", "Base Pull Request") elemBasePR := strings.Split(test.RedirectURL(respBasePR), "/") - assert.EqualValues(t, "pulls", elemBasePR[3]) + assert.Equal(t, "pulls", elemBasePR[3]) // user2 has no permission to delete branch of repo user1/repo1 session2 := loginUser(t, "user2") @@ -665,7 +665,7 @@ func TestPullMergeIndexerNotifier(t *testing.T) { // merge the pull request elem := strings.Split(test.RedirectURL(createPullResp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleMerge, false) // check if the issue is closed @@ -699,7 +699,7 @@ func testResetRepo(t *testing.T, repoPath, branch, commitID string) { defer repo.Close() id, err := repo.GetBranchCommitID(branch) assert.NoError(t, err) - assert.EqualValues(t, commitID, id) + assert.Equal(t, commitID, id) } func TestPullAutoMergeAfterCommitStatusSucceed(t *testing.T) { diff --git a/tests/integration/pull_review_test.go b/tests/integration/pull_review_test.go index cd354e1b6c..3c96e4e6c4 100644 --- a/tests/integration/pull_review_test.go +++ b/tests/integration/pull_review_test.go @@ -119,7 +119,7 @@ func TestPullView_CodeOwner(t *testing.T) { assert.Len(t, reviewNotifiers, 2) reviewerIDs := []int64{reviewNotifiers[0].Reviewer.ID, reviewNotifiers[1].Reviewer.ID} sort.Slice(reviewerIDs, func(i, j int) bool { return reviewerIDs[i] < reviewerIDs[j] }) - assert.EqualValues(t, []int64{5, 8}, reviewerIDs) + assert.Equal(t, []int64{5, 8}, reviewerIDs) reviewNotifiers, err = issue_service.PullRequestCodeOwnersReviewSpecialCommits(db.DefaultContext, pr, resp1.Commit.SHA, resp2.Commit.SHA) assert.NoError(t, err) @@ -130,13 +130,13 @@ func TestPullView_CodeOwner(t *testing.T) { assert.NoError(t, err) prUpdated1 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) assert.NoError(t, prUpdated1.LoadIssue(db.DefaultContext)) - assert.EqualValues(t, "[WIP] Test Pull Request", prUpdated1.Issue.Title) + assert.Equal(t, "[WIP] Test Pull Request", prUpdated1.Issue.Title) err = issue_service.ChangeTitle(db.DefaultContext, prUpdated1.Issue, user2, "Test Pull Request2") assert.NoError(t, err) prUpdated2 := unittest.AssertExistsAndLoadBean(t, &issues_model.PullRequest{ID: pr.ID}) assert.NoError(t, prUpdated2.LoadIssue(db.DefaultContext)) - assert.EqualValues(t, "Test Pull Request2", prUpdated2.Issue.Title) + assert.Equal(t, "Test Pull Request2", prUpdated2.Issue.Title) }) // change the default branch CODEOWNERS file to change README.md's codeowner @@ -229,7 +229,7 @@ func TestPullView_GivenApproveOrRejectReviewOnClosedPR(t *testing.T) { testEditFile(t, user1Session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n") resp := testPullCreate(t, user1Session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, user1Session, elem[1], elem[2], elem[4], repo_model.MergeStyleMerge, false) // Grab the CSRF token. @@ -249,7 +249,7 @@ func TestPullView_GivenApproveOrRejectReviewOnClosedPR(t *testing.T) { testEditFileToNewBranch(t, user1Session, "user1", "repo1", "master", "a-test-branch", "README.md", "Hello, World (Editied...again)\n") resp := testPullCreate(t, user1Session, "user1", "repo1", false, "master", "a-test-branch", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testIssueClose(t, user1Session, elem[1], elem[2], elem[4]) // Grab the CSRF token. diff --git a/tests/integration/pull_status_test.go b/tests/integration/pull_status_test.go index ac9036ca96..63ffe94320 100644 --- a/tests/integration/pull_status_test.go +++ b/tests/integration/pull_status_test.go @@ -86,7 +86,7 @@ func TestPullCreate_CommitStatus(t *testing.T) { commitURL, exists = doc.doc.Find("#commits-table tbody tr td.sha a").Last().Attr("href") assert.True(t, exists) assert.NotEmpty(t, commitURL) - assert.EqualValues(t, commitID, path.Base(commitURL)) + assert.Equal(t, commitID, path.Base(commitURL)) cls, ok := doc.doc.Find("#commits-table tbody tr td.message .commit-status").Last().Attr("class") assert.True(t, ok) @@ -95,7 +95,7 @@ func TestPullCreate_CommitStatus(t *testing.T) { repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{OwnerName: "user1", Name: "repo1"}) css := unittest.AssertExistsAndLoadBean(t, &git_model.CommitStatusSummary{RepoID: repo1.ID, SHA: commitID}) - assert.EqualValues(t, api.CommitStatusWarning, css.State) + assert.Equal(t, api.CommitStatusWarning, css.State) }) } diff --git a/tests/integration/pull_update_test.go b/tests/integration/pull_update_test.go index 7ede84127c..d28537112d 100644 --- a/tests/integration/pull_update_test.go +++ b/tests/integration/pull_update_test.go @@ -33,8 +33,8 @@ func TestAPIPullUpdate(t *testing.T) { // Test GetDiverging diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr) assert.NoError(t, err) - assert.EqualValues(t, 1, diffCount.Behind) - assert.EqualValues(t, 1, diffCount.Ahead) + assert.Equal(t, 1, diffCount.Behind) + assert.Equal(t, 1, diffCount.Ahead) assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) assert.NoError(t, pr.LoadIssue(db.DefaultContext)) @@ -47,8 +47,8 @@ func TestAPIPullUpdate(t *testing.T) { // Test GetDiverging after update diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr) assert.NoError(t, err) - assert.EqualValues(t, 0, diffCount.Behind) - assert.EqualValues(t, 2, diffCount.Ahead) + assert.Equal(t, 0, diffCount.Behind) + assert.Equal(t, 2, diffCount.Ahead) }) } @@ -62,8 +62,8 @@ func TestAPIPullUpdateByRebase(t *testing.T) { // Test GetDiverging diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr) assert.NoError(t, err) - assert.EqualValues(t, 1, diffCount.Behind) - assert.EqualValues(t, 1, diffCount.Ahead) + assert.Equal(t, 1, diffCount.Behind) + assert.Equal(t, 1, diffCount.Ahead) assert.NoError(t, pr.LoadBaseRepo(db.DefaultContext)) assert.NoError(t, pr.LoadIssue(db.DefaultContext)) @@ -76,8 +76,8 @@ func TestAPIPullUpdateByRebase(t *testing.T) { // Test GetDiverging after update diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr) assert.NoError(t, err) - assert.EqualValues(t, 0, diffCount.Behind) - assert.EqualValues(t, 1, diffCount.Ahead) + assert.Equal(t, 0, diffCount.Behind) + assert.Equal(t, 1, diffCount.Ahead) }) } diff --git a/tests/integration/release_test.go b/tests/integration/release_test.go index 1a7f9e38b5..125f0810a7 100644 --- a/tests/integration/release_test.go +++ b/tests/integration/release_test.go @@ -54,12 +54,12 @@ func checkLatestReleaseAndCount(t *testing.T, session *TestSession, repoURL, ver htmlDoc := NewHTMLParser(t, resp.Body) labelText := htmlDoc.doc.Find("#release-list > li .detail .label").First().Text() - assert.EqualValues(t, label, labelText) + assert.Equal(t, label, labelText) titleText := htmlDoc.doc.Find("#release-list > li .detail h4 a").First().Text() - assert.EqualValues(t, version, titleText) + assert.Equal(t, version, titleText) releaseList := htmlDoc.doc.Find("#release-list > li") - assert.EqualValues(t, count, releaseList.Length()) + assert.Equal(t, count, releaseList.Length()) } func TestViewReleases(t *testing.T) { @@ -157,14 +157,14 @@ func TestViewReleaseListNoLogin(t *testing.T) { commitsToMain = append(commitsToMain, s.Find(".ahead > a").Text()) }) - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "/user2/repo-release/releases/tag/empty-target-branch", "/user2/repo-release/releases/tag/non-existing-target-branch", "/user2/repo-release/releases/tag/v2.0", "/user2/repo-release/releases/tag/v1.1", "/user2/repo-release/releases/tag/v1.0", }, links) - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "1 commits", // like v1.1 "1 commits", // like v1.1 "0 commits", @@ -182,8 +182,8 @@ func TestViewSingleRelease(t *testing.T) { htmlDoc := NewHTMLParser(t, resp.Body) // check the "number of commits to main since this release" releaseList := htmlDoc.doc.Find("#release-list .ahead > a") - assert.EqualValues(t, 1, releaseList.Length()) - assert.EqualValues(t, "3 commits", releaseList.First().Text()) + assert.Equal(t, 1, releaseList.Length()) + assert.Equal(t, "3 commits", releaseList.First().Text()) }) t.Run("Login", func(t *testing.T) { session := loginUser(t, "user1") @@ -218,7 +218,7 @@ func TestViewReleaseListLogin(t *testing.T) { links = append(links, link) }) - assert.EqualValues(t, []string{ + assert.Equal(t, []string{ "/user2/repo1/releases/tag/draft-release", "/user2/repo1/releases/tag/v1.0", "/user2/repo1/releases/tag/v1.1", @@ -245,7 +245,7 @@ func TestViewTagsList(t *testing.T) { tagNames = append(tagNames, s.Text()) }) - assert.EqualValues(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames) + assert.Equal(t, []string{"v1.0", "delete-tag", "v1.1"}, tagNames) } func TestDownloadReleaseAttachment(t *testing.T) { diff --git a/tests/integration/repo_activity_test.go b/tests/integration/repo_activity_test.go index b04560379d..d5025decba 100644 --- a/tests/integration/repo_activity_test.go +++ b/tests/integration/repo_activity_test.go @@ -9,7 +9,9 @@ import ( "strings" "testing" + "code.gitea.io/gitea/models/db" repo_model "code.gitea.io/gitea/models/repo" + "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/test" "github.com/stretchr/testify/assert" @@ -24,7 +26,7 @@ func TestRepoActivity(t *testing.T) { testEditFile(t, session, "user1", "repo1", "master", "README.md", "Hello, World (Edited)\n") resp := testPullCreate(t, session, "user1", "repo1", false, "master", "master", "This is a pull title") elem := strings.Split(test.RedirectURL(resp), "/") - assert.EqualValues(t, "pulls", elem[3]) + assert.Equal(t, "pulls", elem[3]) testPullMerge(t, session, elem[1], elem[2], elem[4], repo_model.MergeStyleMerge, false) testEditFileToNewBranch(t, session, "user1", "repo1", "master", "feat/better_readme", "README.md", "Hello, World (Edited Again)\n") @@ -61,5 +63,14 @@ func TestRepoActivity(t *testing.T) { // Should be 3 new issues list = htmlDoc.doc.Find("#new-issues").Next().Find("p.desc") assert.Len(t, list.Nodes, 3) + + // Non-existing default branch + repo1 := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}) + repo1.DefaultBranch = "no-such-branch" + _, _ = db.GetEngine(t.Context()).Cols("default_branch").Update(repo1) + req = NewRequest(t, "GET", "/user2/repo1/activity") + req.Header.Add("Accept", "text/html") + resp = session.MakeRequest(t, req, http.StatusNotFound) + assert.Contains(t, resp.Body.String(), `Default branch "no-such-branch" does not exist.`) }) } diff --git a/tests/integration/repo_branch_test.go b/tests/integration/repo_branch_test.go index f9cf13112a..50ceb65330 100644 --- a/tests/integration/repo_branch_test.go +++ b/tests/integration/repo_branch_test.go @@ -138,7 +138,7 @@ func TestCreateBranchInvalidCSRF(t *testing.T) { } func prepareRecentlyPushedBranchTest(t *testing.T, headSession *TestSession, baseRepo, headRepo *repo_model.Repository) { - refSubURL := fmt.Sprintf("branch/%s", headRepo.DefaultBranch) + refSubURL := "branch/" + headRepo.DefaultBranch baseRepoPath := baseRepo.OwnerName + "/" + baseRepo.Name headRepoPath := headRepo.OwnerName + "/" + headRepo.Name // Case 1: Normal branch changeset to display pushed message @@ -168,7 +168,7 @@ func prepareRecentlyPushedBranchTest(t *testing.T, headSession *TestSession, bas } func prepareRecentlyPushedBranchSpecialTest(t *testing.T, session *TestSession, baseRepo, headRepo *repo_model.Repository) { - refSubURL := fmt.Sprintf("branch/%s", headRepo.DefaultBranch) + refSubURL := "branch/" + headRepo.DefaultBranch baseRepoPath := baseRepo.OwnerName + "/" + baseRepo.Name headRepoPath := headRepo.OwnerName + "/" + headRepo.Name // create branch with no new commit @@ -196,7 +196,7 @@ func testCreatePullToDefaultBranch(t *testing.T, session *TestSession, baseRepo, } func prepareRepoPR(t *testing.T, baseSession, headSession *TestSession, baseRepo, headRepo *repo_model.Repository) { - refSubURL := fmt.Sprintf("branch/%s", headRepo.DefaultBranch) + refSubURL := "branch/" + headRepo.DefaultBranch testCreateBranch(t, headSession, headRepo.OwnerName, headRepo.Name, refSubURL, "new-commit", http.StatusSeeOther) // create opening PR diff --git a/tests/integration/repo_commits_search_test.go b/tests/integration/repo_commits_search_test.go index 74ac25c0f5..9b05e36399 100644 --- a/tests/integration/repo_commits_search_test.go +++ b/tests/integration/repo_commits_search_test.go @@ -23,7 +23,7 @@ func testRepoCommitsSearch(t *testing.T, query, commit string) { doc := NewHTMLParser(t, resp.Body) sel := doc.doc.Find("#commits-table tbody tr td.sha a") - assert.EqualValues(t, commit, strings.TrimSpace(sel.Text())) + assert.Equal(t, commit, strings.TrimSpace(sel.Text())) } func TestRepoCommitsSearch(t *testing.T) { diff --git a/tests/integration/repo_commits_test.go b/tests/integration/repo_commits_test.go index fbe215eb85..dee0aa6176 100644 --- a/tests/integration/repo_commits_test.go +++ b/tests/integration/repo_commits_test.go @@ -58,9 +58,9 @@ func Test_ReposGitCommitListNotMaster(t *testing.T) { }) assert.Len(t, commits, 3) - assert.EqualValues(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", commits[0]) - assert.EqualValues(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", commits[1]) - assert.EqualValues(t, "5099b81332712fe655e34e8dd63574f503f61811", commits[2]) + assert.Equal(t, "69554a64c1e6030f051e5c3f94bfbd773cd6a324", commits[0]) + assert.Equal(t, "27566bd5738fc8b4e3fef3c5e72cce608537bd95", commits[1]) + assert.Equal(t, "5099b81332712fe655e34e8dd63574f503f61811", commits[2]) userNames := []string{} doc.doc.Find("#commits-table .author-wrapper").Each(func(i int, s *goquery.Selection) { @@ -71,9 +71,9 @@ func Test_ReposGitCommitListNotMaster(t *testing.T) { }) assert.Len(t, userNames, 3) - assert.EqualValues(t, "User2", userNames[0]) - assert.EqualValues(t, "user21", userNames[1]) - assert.EqualValues(t, "User2", userNames[2]) + assert.Equal(t, "User2", userNames[0]) + assert.Equal(t, "user21", userNames[1]) + assert.Equal(t, "User2", userNames[2]) } func doTestRepoCommitWithStatus(t *testing.T, state string, classes ...string) { @@ -141,7 +141,7 @@ func testRepoCommitsWithStatus(t *testing.T, resp, respOne *httptest.ResponseRec assert.Equal(t, api.CommitStatusState(state), statuses[0].State) assert.Equal(t, setting.AppURL+"api/v1/repos/user2/repo1/statuses/65f1bf27bc3bf70f64657658635e66094edbcb4d", statuses[0].URL) assert.Equal(t, "http://test.ci/", statuses[0].TargetURL) - assert.Equal(t, "", statuses[0].Description) + assert.Empty(t, statuses[0].Description) assert.Equal(t, "testci", statuses[0].Context) assert.Len(t, status.Statuses, 1) @@ -240,7 +240,7 @@ func TestRepoCommitsStatusMultiple(t *testing.T) { resp = session.MakeRequest(t, req, http.StatusOK) doc = NewHTMLParser(t, resp.Body) - // Check that the data-tippy="commit-statuses" (for trigger) and commit-status (svg) are present - sel := doc.doc.Find("#commits-table .message [data-tippy=\"commit-statuses\"] .commit-status") + // Check that the data-global-init="initCommitStatuses" (for trigger) and commit-status (svg) are present + sel := doc.doc.Find(`#commits-table .message [data-global-init="initCommitStatuses"] .commit-status`) assert.Equal(t, 1, sel.Length()) } diff --git a/tests/integration/repo_fork_test.go b/tests/integration/repo_fork_test.go index cbe5e4bb3f..a7010af14a 100644 --- a/tests/integration/repo_fork_test.go +++ b/tests/integration/repo_fork_test.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "strconv" "testing" "code.gitea.io/gitea/models/db" @@ -46,7 +47,7 @@ func testRepoFork(t *testing.T, session *TestSession, ownerName, repoName, forkO assert.True(t, exists, "Fork owner '%s' is not present in select box", forkOwnerName) req = NewRequestWithValues(t, "POST", link, map[string]string{ "_csrf": htmlDoc.GetCSRF(), - "uid": fmt.Sprintf("%d", forkOwner.ID), + "uid": strconv.FormatInt(forkOwner.ID, 10), "repo_name": forkRepoName, "fork_single_branch": forkBranch, }) @@ -88,7 +89,7 @@ func TestForkListLimitedAndPrivateRepos(t *testing.T) { // fork to a limited org limitedOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 22}) - assert.EqualValues(t, structs.VisibleTypeLimited, limitedOrg.Visibility) + assert.Equal(t, structs.VisibleTypeLimited, limitedOrg.Visibility) ownerTeam1, err := org_model.OrgFromUser(limitedOrg).GetOwnerTeam(db.DefaultContext) assert.NoError(t, err) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam1, user1)) @@ -98,7 +99,7 @@ func TestForkListLimitedAndPrivateRepos(t *testing.T) { user4Sess := loginUser(t, "user4") user4 := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user4"}) privateOrg := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 23}) - assert.EqualValues(t, structs.VisibleTypePrivate, privateOrg.Visibility) + assert.Equal(t, structs.VisibleTypePrivate, privateOrg.Visibility) ownerTeam2, err := org_model.OrgFromUser(privateOrg).GetOwnerTeam(db.DefaultContext) assert.NoError(t, err) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user4)) @@ -109,7 +110,7 @@ func TestForkListLimitedAndPrivateRepos(t *testing.T) { req := NewRequest(t, "GET", "/user2/repo1/forks") resp := MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - assert.EqualValues(t, 0, htmlDoc.Find(forkItemSelector).Length()) + assert.Equal(t, 0, htmlDoc.Find(forkItemSelector).Length()) }) t.Run("Logged in", func(t *testing.T) { @@ -119,11 +120,11 @@ func TestForkListLimitedAndPrivateRepos(t *testing.T) { resp := user1Sess.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) // since user1 is an admin, he can get both of the forked repositories - assert.EqualValues(t, 2, htmlDoc.Find(forkItemSelector).Length()) + assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length()) assert.NoError(t, org_service.AddTeamMember(db.DefaultContext, ownerTeam2, user1)) resp = user1Sess.MakeRequest(t, req, http.StatusOK) htmlDoc = NewHTMLParser(t, resp.Body) - assert.EqualValues(t, 2, htmlDoc.Find(forkItemSelector).Length()) + assert.Equal(t, 2, htmlDoc.Find(forkItemSelector).Length()) }) } diff --git a/tests/integration/repo_generate_test.go b/tests/integration/repo_generate_test.go index f5645d62bc..fca4e92982 100644 --- a/tests/integration/repo_generate_test.go +++ b/tests/integration/repo_generate_test.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/http/httptest" + "strconv" "strings" "testing" @@ -44,7 +45,7 @@ func testRepoGenerate(t *testing.T, session *TestSession, templateID, templateOw assert.True(t, exists, "Generate owner '%s' is not present in select box", generateOwnerName) req = NewRequestWithValues(t, "POST", link, map[string]string{ "_csrf": htmlDoc.GetCSRF(), - "uid": fmt.Sprintf("%d", generateOwner.ID), + "uid": strconv.FormatInt(generateOwner.ID, 10), "repo_name": generateRepoName, "repo_template": templateID, "git_content": "true", diff --git a/tests/integration/repo_search_test.go b/tests/integration/repo_search_test.go index 29d1517f4e..36a2e81f3b 100644 --- a/tests/integration/repo_search_test.go +++ b/tests/integration/repo_search_test.go @@ -57,5 +57,5 @@ func testSearch(t *testing.T, url string, expected []string) { resp := MakeRequest(t, req, http.StatusOK) filenames := resultFilenames(NewHTMLParser(t, resp.Body)) - assert.EqualValues(t, expected, filenames) + assert.Equal(t, expected, filenames) } diff --git a/tests/integration/repo_test.go b/tests/integration/repo_test.go index 9a3cb988a6..da5aaf3da0 100644 --- a/tests/integration/repo_test.go +++ b/tests/integration/repo_test.go @@ -102,7 +102,7 @@ func testViewRepoWithCache(t *testing.T) { }) commitT := time.Date(2017, time.June, 14, 13, 54, 21, 0, time.UTC).In(time.Local).Format(time.RFC1123) - assert.EqualValues(t, []file{ + assert.Equal(t, []file{ { fileName: "doc", commitID: "2a47ca4b614a9f5a43abbd5ad851a54a616ffee6", @@ -250,9 +250,9 @@ func testViewFileInRepo(t *testing.T) { repoTopics := htmlDoc.doc.Find("#repo-topics") repoSummary := htmlDoc.doc.Find(".repository-summary") - assert.EqualValues(t, 0, description.Length()) - assert.EqualValues(t, 0, repoTopics.Length()) - assert.EqualValues(t, 0, repoSummary.Length()) + assert.Equal(t, 0, description.Length()) + assert.Equal(t, 0, repoTopics.Length()) + assert.Equal(t, 0, repoSummary.Length()) } // TestBlameFileInRepo repo description, topics and summary should not be displayed when running blame on a file @@ -269,9 +269,9 @@ func testBlameFileInRepo(t *testing.T) { repoTopics := htmlDoc.doc.Find("#repo-topics") repoSummary := htmlDoc.doc.Find(".repository-summary") - assert.EqualValues(t, 0, description.Length()) - assert.EqualValues(t, 0, repoTopics.Length()) - assert.EqualValues(t, 0, repoSummary.Length()) + assert.Equal(t, 0, description.Length()) + assert.Equal(t, 0, repoTopics.Length()) + assert.Equal(t, 0, repoSummary.Length()) } // TestViewRepoDirectory repo description, topics and summary should not be displayed when within a directory diff --git a/tests/integration/repo_topic_test.go b/tests/integration/repo_topic_test.go index f198397007..7f9594b9fd 100644 --- a/tests/integration/repo_topic_test.go +++ b/tests/integration/repo_topic_test.go @@ -25,7 +25,7 @@ func TestTopicSearch(t *testing.T) { res := MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 6) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // pagination search topics topics.TopicNames = nil @@ -35,7 +35,7 @@ func TestTopicSearch(t *testing.T) { res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 4) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // second page topics.TopicNames = nil @@ -45,7 +45,7 @@ func TestTopicSearch(t *testing.T) { res = MakeRequest(t, NewRequest(t, "GET", searchURL.String()), http.StatusOK) DecodeJSON(t, res, &topics) assert.Len(t, topics.TopicNames, 2) - assert.EqualValues(t, "6", res.Header().Get("x-total-count")) + assert.Equal(t, "6", res.Header().Get("x-total-count")) // add keyword search topics.TopicNames = nil @@ -63,7 +63,7 @@ func TestTopicSearch(t *testing.T) { DecodeJSON(t, res, &topics) if assert.Len(t, topics.TopicNames, 1) { assert.EqualValues(t, 2, topics.TopicNames[0].ID) - assert.EqualValues(t, "database", topics.TopicNames[0].Name) - assert.EqualValues(t, 1, topics.TopicNames[0].RepoCount) + assert.Equal(t, "database", topics.TopicNames[0].Name) + assert.Equal(t, 1, topics.TopicNames[0].RepoCount) } } diff --git a/tests/integration/repo_webhook_test.go b/tests/integration/repo_webhook_test.go index 7e85c10d4b..89df15b8de 100644 --- a/tests/integration/repo_webhook_test.go +++ b/tests/integration/repo_webhook_test.go @@ -149,11 +149,11 @@ func Test_WebhookCreate(t *testing.T) { // 3. validate the webhook is triggered assert.Len(t, payloads, 1) - assert.EqualValues(t, string(webhook_module.HookEventCreate), triggeredEvent) - assert.EqualValues(t, "repo1", payloads[0].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) - assert.EqualValues(t, "master2", payloads[0].Ref) - assert.EqualValues(t, "branch", payloads[0].RefType) + assert.Equal(t, string(webhook_module.HookEventCreate), triggeredEvent) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Equal(t, "master2", payloads[0].Ref) + assert.Equal(t, "branch", payloads[0].RefType) }) } @@ -181,12 +181,12 @@ func Test_WebhookDelete(t *testing.T) { testAPIDeleteBranch(t, "master2", http.StatusNoContent) // 3. validate the webhook is triggered - assert.EqualValues(t, "delete", triggeredEvent) + assert.Equal(t, "delete", triggeredEvent) assert.Len(t, payloads, 1) - assert.EqualValues(t, "repo1", payloads[0].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) - assert.EqualValues(t, "master2", payloads[0].Ref) - assert.EqualValues(t, "branch", payloads[0].RefType) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Equal(t, "master2", payloads[0].Ref) + assert.Equal(t, "branch", payloads[0].RefType) }) } @@ -213,12 +213,12 @@ func Test_WebhookFork(t *testing.T) { testRepoFork(t, session, "user2", "repo1", "user1", "repo1-fork", "master") // 3. validate the webhook is triggered - assert.EqualValues(t, "fork", triggeredEvent) + assert.Equal(t, "fork", triggeredEvent) assert.Len(t, payloads, 1) - assert.EqualValues(t, "repo1-fork", payloads[0].Repo.Name) - assert.EqualValues(t, "user1/repo1-fork", payloads[0].Repo.FullName) - assert.EqualValues(t, "repo1", payloads[0].Forkee.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Forkee.FullName) + assert.Equal(t, "repo1-fork", payloads[0].Repo.Name) + assert.Equal(t, "user1/repo1-fork", payloads[0].Repo.FullName) + assert.Equal(t, "repo1", payloads[0].Forkee.Name) + assert.Equal(t, "user2/repo1", payloads[0].Forkee.FullName) }) } @@ -246,14 +246,14 @@ func Test_WebhookIssueComment(t *testing.T) { testIssueAddComment(t, session, issueURL, "issue title2 comment1", "") // 3. validate the webhook is triggered - assert.EqualValues(t, "issue_comment", triggeredEvent) + assert.Equal(t, "issue_comment", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "created", payloads[0].Action) - assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) - assert.EqualValues(t, "Title2", payloads[0].Issue.Title) - assert.EqualValues(t, "Description2", payloads[0].Issue.Body) - assert.EqualValues(t, "issue title2 comment1", payloads[0].Comment.Body) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "Title2", payloads[0].Issue.Title) + assert.Equal(t, "Description2", payloads[0].Issue.Body) + assert.Equal(t, "issue title2 comment1", payloads[0].Comment.Body) }) } @@ -280,11 +280,11 @@ func Test_WebhookRelease(t *testing.T) { createNewRelease(t, session, "/user2/repo1", "v0.0.99", "v0.0.99", false, false) // 3. validate the webhook is triggered - assert.EqualValues(t, "release", triggeredEvent) + assert.Equal(t, "release", triggeredEvent) assert.Len(t, payloads, 1) - assert.EqualValues(t, "repo1", payloads[0].Repository.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repository.FullName) - assert.EqualValues(t, "v0.0.99", payloads[0].Release.TagName) + assert.Equal(t, "repo1", payloads[0].Repository.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repository.FullName) + assert.Equal(t, "v0.0.99", payloads[0].Release.TagName) assert.False(t, payloads[0].Release.IsDraft) assert.False(t, payloads[0].Release.IsPrerelease) }) @@ -313,12 +313,12 @@ func Test_WebhookPush(t *testing.T) { testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push") // 3. validate the webhook is triggered - assert.EqualValues(t, "push", triggeredEvent) + assert.Equal(t, "push", triggeredEvent) assert.Len(t, payloads, 1) - assert.EqualValues(t, "repo1", payloads[0].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) assert.Len(t, payloads[0].Commits, 1) - assert.EqualValues(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added) + assert.Equal(t, []string{"test_webhook_push.md"}, payloads[0].Commits[0].Added) }) } @@ -345,13 +345,13 @@ func Test_WebhookIssue(t *testing.T) { testNewIssue(t, session, "user2", "repo1", "Title1", "Description1") // 3. validate the webhook is triggered - assert.EqualValues(t, "issues", triggeredEvent) + assert.Equal(t, "issues", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "opened", payloads[0].Action) - assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) - assert.EqualValues(t, "Title1", payloads[0].Issue.Title) - assert.EqualValues(t, "Description1", payloads[0].Issue.Body) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "Title1", payloads[0].Issue.Title) + assert.Equal(t, "Description1", payloads[0].Issue.Body) }) } @@ -380,15 +380,15 @@ func Test_WebhookPullRequest(t *testing.T) { testCreatePullToDefaultBranch(t, session, repo1, repo1, "master2", "first pull request") // 3. validate the webhook is triggered - assert.EqualValues(t, "pull_request", triggeredEvent) + assert.Equal(t, "pull_request", triggeredEvent) require.Len(t, payloads, 1) - assert.EqualValues(t, "repo1", payloads[0].PullRequest.Base.Repository.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].PullRequest.Base.Repository.FullName) - assert.EqualValues(t, "repo1", payloads[0].PullRequest.Head.Repository.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].PullRequest.Head.Repository.FullName) - assert.EqualValues(t, 0, *payloads[0].PullRequest.Additions) - assert.EqualValues(t, 0, *payloads[0].PullRequest.ChangedFiles) - assert.EqualValues(t, 0, *payloads[0].PullRequest.Deletions) + assert.Equal(t, "repo1", payloads[0].PullRequest.Base.Repository.Name) + assert.Equal(t, "user2/repo1", payloads[0].PullRequest.Base.Repository.FullName) + assert.Equal(t, "repo1", payloads[0].PullRequest.Head.Repository.Name) + assert.Equal(t, "user2/repo1", payloads[0].PullRequest.Head.Repository.FullName) + assert.Equal(t, 0, *payloads[0].PullRequest.Additions) + assert.Equal(t, 0, *payloads[0].PullRequest.ChangedFiles) + assert.Equal(t, 0, *payloads[0].PullRequest.Deletions) }) } @@ -419,14 +419,14 @@ func Test_WebhookPullRequestComment(t *testing.T) { testIssueAddComment(t, session, "/user2/repo1/pulls/"+prID, "pull title2 comment1", "") // 3. validate the webhook is triggered - assert.EqualValues(t, "pull_request_comment", triggeredEvent) + assert.Equal(t, "pull_request_comment", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "created", payloads[0].Action) - assert.EqualValues(t, "repo1", payloads[0].Issue.Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Issue.Repo.FullName) - assert.EqualValues(t, "first pull request", payloads[0].Issue.Title) - assert.EqualValues(t, "", payloads[0].Issue.Body) - assert.EqualValues(t, "pull title2 comment1", payloads[0].Comment.Body) + assert.Equal(t, "repo1", payloads[0].Issue.Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Issue.Repo.FullName) + assert.Equal(t, "first pull request", payloads[0].Issue.Title) + assert.Empty(t, payloads[0].Issue.Body) + assert.Equal(t, "pull title2 comment1", payloads[0].Comment.Body) }) } @@ -453,12 +453,12 @@ func Test_WebhookWiki(t *testing.T) { testAPICreateWikiPage(t, session, "user2", "repo1", "Test Wiki Page", http.StatusCreated) // 3. validate the webhook is triggered - assert.EqualValues(t, "wiki", triggeredEvent) + assert.Equal(t, "wiki", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "created", payloads[0].Action) - assert.EqualValues(t, "repo1", payloads[0].Repository.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repository.FullName) - assert.EqualValues(t, "Test-Wiki-Page", payloads[0].Page) + assert.Equal(t, "repo1", payloads[0].Repository.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repository.FullName) + assert.Equal(t, "Test-Wiki-Page", payloads[0].Page) }) } @@ -485,12 +485,12 @@ func Test_WebhookRepository(t *testing.T) { testAPIOrgCreateRepo(t, session, "org3", "repo_new", http.StatusCreated) // 3. validate the webhook is triggered - assert.EqualValues(t, "repository", triggeredEvent) + assert.Equal(t, "repository", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "created", payloads[0].Action) - assert.EqualValues(t, "org3", payloads[0].Organization.UserName) - assert.EqualValues(t, "repo_new", payloads[0].Repository.Name) - assert.EqualValues(t, "org3/repo_new", payloads[0].Repository.FullName) + assert.Equal(t, "org3", payloads[0].Organization.UserName) + assert.Equal(t, "repo_new", payloads[0].Repository.Name) + assert.Equal(t, "org3/repo_new", payloads[0].Repository.FullName) }) } @@ -521,13 +521,13 @@ func Test_WebhookPackage(t *testing.T) { MakeRequest(t, req, http.StatusCreated) // 3. validate the webhook is triggered - assert.EqualValues(t, "package", triggeredEvent) + assert.Equal(t, "package", triggeredEvent) assert.Len(t, payloads, 1) assert.EqualValues(t, "created", payloads[0].Action) - assert.EqualValues(t, "gitea", payloads[0].Package.Name) - assert.EqualValues(t, "generic", payloads[0].Package.Type) - assert.EqualValues(t, "org3", payloads[0].Organization.UserName) - assert.EqualValues(t, "v1.24.0", payloads[0].Package.Version) + assert.Equal(t, "gitea", payloads[0].Package.Name) + assert.Equal(t, "generic", payloads[0].Package.Type) + assert.Equal(t, "org3", payloads[0].Organization.UserName) + assert.Equal(t, "v1.24.0", payloads[0].Package.Version) }) } @@ -574,13 +574,13 @@ func Test_WebhookStatus(t *testing.T) { })(t) // 3. validate the webhook is triggered - assert.EqualValues(t, "status", triggeredEvent) + assert.Equal(t, "status", triggeredEvent) assert.Len(t, payloads, 1) - assert.EqualValues(t, commitID, payloads[0].Commit.ID) - assert.EqualValues(t, "repo1", payloads[0].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) - assert.EqualValues(t, "testci", payloads[0].Context) - assert.EqualValues(t, commitID, payloads[0].SHA) + assert.Equal(t, commitID, payloads[0].Commit.ID) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Equal(t, "testci", payloads[0].Context) + assert.Equal(t, commitID, payloads[0].SHA) }) } @@ -605,7 +605,7 @@ func Test_WebhookStatus_NoWrongTrigger(t *testing.T) { testCreateFile(t, session, "user2", "repo1", "master", "test_webhook_push.md", "# a test file for webhook push") // 3. validate the webhook is triggered with right event - assert.EqualValues(t, "push", trigger) + assert.Equal(t, "push", trigger) }) } @@ -660,27 +660,27 @@ jobs: - run: echo 'cmd 1' - run: echo 'cmd 2' ` - opts := getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, fmt.Sprintf("create %s", wfTreePath), wfFileContent) + opts := getWorkflowCreateFileOptions(user2, repo1.DefaultBranch, "create "+wfTreePath, wfFileContent) createWorkflowFile(t, token, "user2", "repo1", wfTreePath, opts) commitID, err := gitRepo1.GetBranchCommitID(repo1.DefaultBranch) assert.NoError(t, err) // 3. validate the webhook is triggered - assert.EqualValues(t, "workflow_job", triggeredEvent) + assert.Equal(t, "workflow_job", triggeredEvent) assert.Len(t, payloads, 2) - assert.EqualValues(t, "queued", payloads[0].Action) - assert.EqualValues(t, "queued", payloads[0].WorkflowJob.Status) - assert.EqualValues(t, []string{"ubuntu-latest"}, payloads[0].WorkflowJob.Labels) - assert.EqualValues(t, commitID, payloads[0].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[0].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[0].Repo.FullName) + assert.Equal(t, "queued", payloads[0].Action) + assert.Equal(t, "queued", payloads[0].WorkflowJob.Status) + assert.Equal(t, []string{"ubuntu-latest"}, payloads[0].WorkflowJob.Labels) + assert.Equal(t, commitID, payloads[0].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[0].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[0].Repo.FullName) - assert.EqualValues(t, "waiting", payloads[1].Action) - assert.EqualValues(t, "waiting", payloads[1].WorkflowJob.Status) - assert.EqualValues(t, commitID, payloads[1].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[1].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[1].Repo.FullName) + assert.Equal(t, "waiting", payloads[1].Action) + assert.Equal(t, "waiting", payloads[1].WorkflowJob.Status) + assert.Equal(t, commitID, payloads[1].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[1].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[1].Repo.FullName) // 4. Execute a single Job task := runner.fetchTask(t) @@ -691,33 +691,33 @@ jobs: runner.execTask(t, task, outcome) // 5. validate the webhook is triggered - assert.EqualValues(t, "workflow_job", triggeredEvent) + assert.Equal(t, "workflow_job", triggeredEvent) assert.Len(t, payloads, 5) - assert.EqualValues(t, "in_progress", payloads[2].Action) - assert.EqualValues(t, "in_progress", payloads[2].WorkflowJob.Status) - assert.EqualValues(t, "mock-runner", payloads[2].WorkflowJob.RunnerName) - assert.EqualValues(t, commitID, payloads[2].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[2].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[2].Repo.FullName) + assert.Equal(t, "in_progress", payloads[2].Action) + assert.Equal(t, "in_progress", payloads[2].WorkflowJob.Status) + assert.Equal(t, "mock-runner", payloads[2].WorkflowJob.RunnerName) + assert.Equal(t, commitID, payloads[2].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[2].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[2].Repo.FullName) - assert.EqualValues(t, "completed", payloads[3].Action) - assert.EqualValues(t, "completed", payloads[3].WorkflowJob.Status) - assert.EqualValues(t, "mock-runner", payloads[3].WorkflowJob.RunnerName) - assert.EqualValues(t, "success", payloads[3].WorkflowJob.Conclusion) - assert.EqualValues(t, commitID, payloads[3].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[3].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[3].Repo.FullName) + assert.Equal(t, "completed", payloads[3].Action) + assert.Equal(t, "completed", payloads[3].WorkflowJob.Status) + assert.Equal(t, "mock-runner", payloads[3].WorkflowJob.RunnerName) + assert.Equal(t, "success", payloads[3].WorkflowJob.Conclusion) + assert.Equal(t, commitID, payloads[3].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[3].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[3].Repo.FullName) assert.Contains(t, payloads[3].WorkflowJob.URL, fmt.Sprintf("/actions/runs/%d/jobs/%d", payloads[3].WorkflowJob.RunID, payloads[3].WorkflowJob.ID)) assert.Contains(t, payloads[3].WorkflowJob.URL, payloads[3].WorkflowJob.RunURL) assert.Contains(t, payloads[3].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", 0)) assert.Len(t, payloads[3].WorkflowJob.Steps, 1) - assert.EqualValues(t, "queued", payloads[4].Action) - assert.EqualValues(t, "queued", payloads[4].WorkflowJob.Status) - assert.EqualValues(t, []string{"ubuntu-latest"}, payloads[4].WorkflowJob.Labels) - assert.EqualValues(t, commitID, payloads[4].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[4].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[4].Repo.FullName) + assert.Equal(t, "queued", payloads[4].Action) + assert.Equal(t, "queued", payloads[4].WorkflowJob.Status) + assert.Equal(t, []string{"ubuntu-latest"}, payloads[4].WorkflowJob.Labels) + assert.Equal(t, commitID, payloads[4].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[4].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[4].Repo.FullName) // 6. Execute a single Job task = runner.fetchTask(t) @@ -728,23 +728,23 @@ jobs: runner.execTask(t, task, outcome) // 7. validate the webhook is triggered - assert.EqualValues(t, "workflow_job", triggeredEvent) + assert.Equal(t, "workflow_job", triggeredEvent) assert.Len(t, payloads, 7) - assert.EqualValues(t, "in_progress", payloads[5].Action) - assert.EqualValues(t, "in_progress", payloads[5].WorkflowJob.Status) - assert.EqualValues(t, "mock-runner", payloads[5].WorkflowJob.RunnerName) + assert.Equal(t, "in_progress", payloads[5].Action) + assert.Equal(t, "in_progress", payloads[5].WorkflowJob.Status) + assert.Equal(t, "mock-runner", payloads[5].WorkflowJob.RunnerName) - assert.EqualValues(t, commitID, payloads[5].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[5].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[5].Repo.FullName) + assert.Equal(t, commitID, payloads[5].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[5].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[5].Repo.FullName) - assert.EqualValues(t, "completed", payloads[6].Action) - assert.EqualValues(t, "completed", payloads[6].WorkflowJob.Status) - assert.EqualValues(t, "failure", payloads[6].WorkflowJob.Conclusion) - assert.EqualValues(t, "mock-runner", payloads[6].WorkflowJob.RunnerName) - assert.EqualValues(t, commitID, payloads[6].WorkflowJob.HeadSha) - assert.EqualValues(t, "repo1", payloads[6].Repo.Name) - assert.EqualValues(t, "user2/repo1", payloads[6].Repo.FullName) + assert.Equal(t, "completed", payloads[6].Action) + assert.Equal(t, "completed", payloads[6].WorkflowJob.Status) + assert.Equal(t, "failure", payloads[6].WorkflowJob.Conclusion) + assert.Equal(t, "mock-runner", payloads[6].WorkflowJob.RunnerName) + assert.Equal(t, commitID, payloads[6].WorkflowJob.HeadSha) + assert.Equal(t, "repo1", payloads[6].Repo.Name) + assert.Equal(t, "user2/repo1", payloads[6].Repo.FullName) assert.Contains(t, payloads[6].WorkflowJob.URL, fmt.Sprintf("/actions/runs/%d/jobs/%d", payloads[6].WorkflowJob.RunID, payloads[6].WorkflowJob.ID)) assert.Contains(t, payloads[6].WorkflowJob.URL, payloads[6].WorkflowJob.RunURL) assert.Contains(t, payloads[6].WorkflowJob.HTMLURL, fmt.Sprintf("/jobs/%d", 1)) diff --git a/tests/integration/repofiles_change_test.go b/tests/integration/repofiles_change_test.go index ef520a2e51..ce55a2f943 100644 --- a/tests/integration/repofiles_change_test.go +++ b/tests/integration/repofiles_change_test.go @@ -4,8 +4,9 @@ package integration import ( + "fmt" "net/url" - "path/filepath" + "path" "strings" "testing" "time" @@ -78,7 +79,7 @@ func getDeleteRepoFilesOptions(repo *repo_model.Repository) *files_service.Chang } } -func getExpectedFileResponseForRepofilesDelete() *api.FileResponse { +func getExpectedFileResponseForRepoFilesDelete() *api.FileResponse { // Just returns fields that don't change, i.e. fields with commit SHAs and dates can't be determined return &api.FileResponse{ Content: nil, @@ -106,7 +107,7 @@ func getExpectedFileResponseForRepofilesDelete() *api.FileResponse { } } -func getExpectedFileResponseForRepofilesCreate(commitID, lastCommitSHA string) *api.FileResponse { +func getExpectedFileResponseForRepoFilesCreate(commitID string, lastCommit *git.Commit) *api.FileResponse { treePath := "new/file.txt" encoding := "base64" content := "VGhpcyBpcyBhIE5FVyBmaWxl" @@ -116,18 +117,20 @@ func getExpectedFileResponseForRepofilesCreate(commitID, lastCommitSHA string) * downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + treePath return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filepath.Base(treePath), - Path: treePath, - SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885", - LastCommitSHA: lastCommitSHA, - Type: "file", - Size: 18, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: path.Base(treePath), + Path: treePath, + SHA: "103ff9234cefeee5ec5361d22b49fbb04d385885", + LastCommitSHA: lastCommit.ID.String(), + LastCommitterDate: lastCommit.Committer.When, + LastAuthorDate: lastCommit.Author.When, + Type: "file", + Size: 18, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -175,7 +178,7 @@ func getExpectedFileResponseForRepofilesCreate(commitID, lastCommitSHA string) * } } -func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA string) *api.FileResponse { +func getExpectedFileResponseForRepoFilesUpdate(commitID, filename, lastCommitSHA string, lastCommitterWhen, lastAuthorWhen time.Time) *api.FileResponse { encoding := "base64" content := "VGhpcyBpcyBVUERBVEVEIGNvbnRlbnQgZm9yIHRoZSBSRUFETUUgZmlsZQ==" selfURL := setting.AppURL + "api/v1/repos/user2/repo1/contents/" + filename + "?ref=master" @@ -184,18 +187,20 @@ func getExpectedFileResponseForRepofilesUpdate(commitID, filename, lastCommitSHA downloadURL := setting.AppURL + "user2/repo1/raw/branch/master/" + filename return &api.FileResponse{ Content: &api.ContentsResponse{ - Name: filename, - Path: filename, - SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647", - LastCommitSHA: lastCommitSHA, - Type: "file", - Size: 43, - Encoding: &encoding, - Content: &content, - URL: &selfURL, - HTMLURL: &htmlURL, - GitURL: &gitURL, - DownloadURL: &downloadURL, + Name: filename, + Path: filename, + SHA: "dbf8d00e022e05b7e5cf7e535de857de57925647", + LastCommitSHA: lastCommitSHA, + LastCommitterDate: lastCommitterWhen, + LastAuthorDate: lastAuthorWhen, + Type: "file", + Size: 43, + Encoding: &encoding, + Content: &content, + URL: &selfURL, + HTMLURL: &htmlURL, + GitURL: &gitURL, + DownloadURL: &downloadURL, Links: &api.FileLinksResponse{ Self: &selfURL, GitURL: &gitURL, @@ -268,14 +273,14 @@ func TestChangeRepoFilesForCreate(t *testing.T) { commitID, _ := gitRepo.GetBranchCommitID(opts.NewBranch) lastCommit, _ := gitRepo.GetCommitByPath("new/file.txt") - expectedFileResponse := getExpectedFileResponseForRepofilesCreate(commitID, lastCommit.ID.String()) + expectedFileResponse := getExpectedFileResponseForRepoFilesCreate(commitID, lastCommit) assert.NotNil(t, expectedFileResponse) if expectedFileResponse != nil { - assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) + assert.Equal(t, expectedFileResponse.Content, filesResponse.Files[0]) + assert.Equal(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) + assert.Equal(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) } }) } @@ -305,12 +310,12 @@ func TestChangeRepoFilesForUpdate(t *testing.T) { commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) - assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) + expectedFileResponse := getExpectedFileResponseForRepoFilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String(), lastCommit.Committer.When, lastCommit.Author.When) + assert.Equal(t, expectedFileResponse.Content, filesResponse.Files[0]) + assert.Equal(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Commit.Author.Email, filesResponse.Commit.Author.Email) + assert.Equal(t, expectedFileResponse.Commit.Author.Name, filesResponse.Commit.Author.Name) }) } @@ -341,7 +346,7 @@ func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) { commit, _ := gitRepo.GetBranchCommit(opts.NewBranch) lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) + expectedFileResponse := getExpectedFileResponseForRepoFilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String(), lastCommit.Committer.When, lastCommit.Author.When) // assert that the old file no longer exists in the last commit of the branch fromEntry, err := commit.GetTreeEntryByPath(opts.Files[0].FromTreePath) switch err.(type) { @@ -355,12 +360,12 @@ func TestChangeRepoFilesForUpdateWithFileMove(t *testing.T) { assert.Nil(t, fromEntry) // Should no longer exist here assert.NotNil(t, toEntry) // Should exist here // assert SHA has remained the same but paths use the new file name - assert.EqualValues(t, expectedFileResponse.Content.SHA, filesResponse.Files[0].SHA) - assert.EqualValues(t, expectedFileResponse.Content.Name, filesResponse.Files[0].Name) - assert.EqualValues(t, expectedFileResponse.Content.Path, filesResponse.Files[0].Path) - assert.EqualValues(t, expectedFileResponse.Content.URL, filesResponse.Files[0].URL) - assert.EqualValues(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) - assert.EqualValues(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) + assert.Equal(t, expectedFileResponse.Content.SHA, filesResponse.Files[0].SHA) + assert.Equal(t, expectedFileResponse.Content.Name, filesResponse.Files[0].Name) + assert.Equal(t, expectedFileResponse.Content.Path, filesResponse.Files[0].Path) + assert.Equal(t, expectedFileResponse.Content.URL, filesResponse.Files[0].URL) + assert.Equal(t, expectedFileResponse.Commit.SHA, filesResponse.Commit.SHA) + assert.Equal(t, expectedFileResponse.Commit.HTMLURL, filesResponse.Commit.HTMLURL) }) } @@ -392,8 +397,8 @@ func TestChangeRepoFilesWithoutBranchNames(t *testing.T) { commit, _ := gitRepo.GetBranchCommit(repo.DefaultBranch) lastCommit, _ := commit.GetCommitByPath(opts.Files[0].TreePath) - expectedFileResponse := getExpectedFileResponseForRepofilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String()) - assert.EqualValues(t, expectedFileResponse.Content, filesResponse.Files[0]) + expectedFileResponse := getExpectedFileResponseForRepoFilesUpdate(commit.ID.String(), opts.Files[0].TreePath, lastCommit.ID.String(), lastCommit.Committer.When, lastCommit.Author.When) + assert.Equal(t, expectedFileResponse.Content, filesResponse.Files[0]) }) } @@ -418,13 +423,13 @@ func testDeleteRepoFiles(t *testing.T, u *url.URL) { t.Run("Delete README.md file", func(t *testing.T) { filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) assert.NoError(t, err) - expectedFileResponse := getExpectedFileResponseForRepofilesDelete() + expectedFileResponse := getExpectedFileResponseForRepoFilesDelete() assert.NotNil(t, filesResponse) assert.Nil(t, filesResponse.Files[0]) - assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) - assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) + assert.Equal(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) + assert.Equal(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) + assert.Equal(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) + assert.Equal(t, expectedFileResponse.Verification, filesResponse.Verification) }) t.Run("Verify README.md has been deleted", func(t *testing.T) { @@ -460,13 +465,13 @@ func testDeleteRepoFilesWithoutBranchNames(t *testing.T, u *url.URL) { t.Run("Delete README.md without Branch Name", func(t *testing.T) { filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) assert.NoError(t, err) - expectedFileResponse := getExpectedFileResponseForRepofilesDelete() + expectedFileResponse := getExpectedFileResponseForRepoFilesDelete() assert.NotNil(t, filesResponse) assert.Nil(t, filesResponse.Files[0]) - assert.EqualValues(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) - assert.EqualValues(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) - assert.EqualValues(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) - assert.EqualValues(t, expectedFileResponse.Verification, filesResponse.Verification) + assert.Equal(t, expectedFileResponse.Commit.Message, filesResponse.Commit.Message) + assert.Equal(t, expectedFileResponse.Commit.Author.Identity, filesResponse.Commit.Author.Identity) + assert.Equal(t, expectedFileResponse.Commit.Committer.Identity, filesResponse.Commit.Committer.Identity) + assert.Equal(t, expectedFileResponse.Verification, filesResponse.Verification) }) } @@ -490,7 +495,7 @@ func TestChangeRepoFilesErrors(t *testing.T) { filesResponse, err := files_service.ChangeRepoFiles(git.DefaultContext, repo, doer, opts) assert.Error(t, err) assert.Nil(t, filesResponse) - expectedError := "branch does not exist [name: " + opts.OldBranch + "]" + expectedError := fmt.Sprintf("branch does not exist [repo_id: %d name: %s]", repo.ID, opts.OldBranch) assert.EqualError(t, err, expectedError) }) diff --git a/tests/integration/session_test.go b/tests/integration/session_test.go index b18a25827d..f72e2e24b7 100644 --- a/tests/integration/session_test.go +++ b/tests/integration/session_test.go @@ -27,11 +27,11 @@ func Test_RegenerateSession(t *testing.T) { sess, err := auth.RegenerateSession(db.DefaultContext, "", key) assert.NoError(t, err) - assert.EqualValues(t, key, sess.Key) + assert.Equal(t, key, sess.Key) assert.Empty(t, sess.Data) sess, err = auth.ReadSession(db.DefaultContext, key2) assert.NoError(t, err) - assert.EqualValues(t, key2, sess.Key) + assert.Equal(t, key2, sess.Key) assert.Empty(t, sess.Data) } diff --git a/tests/integration/signin_test.go b/tests/integration/signin_test.go index 5c7555286e..67af5b5877 100644 --- a/tests/integration/signin_test.go +++ b/tests/integration/signin_test.go @@ -16,6 +16,7 @@ import ( "code.gitea.io/gitea/modules/test" "code.gitea.io/gitea/modules/translation" "code.gitea.io/gitea/modules/web" + "code.gitea.io/gitea/routers" "code.gitea.io/gitea/services/context" "code.gitea.io/gitea/tests" @@ -35,7 +36,7 @@ func testLoginFailed(t *testing.T, username, password, message string) { htmlDoc := NewHTMLParser(t, resp.Body) resultMsg := htmlDoc.doc.Find(".ui.message>p").Text() - assert.EqualValues(t, message, resultMsg) + assert.Equal(t, message, resultMsg) } func TestSignin(t *testing.T) { @@ -166,3 +167,32 @@ func TestEnablePasswordSignInFormAndEnablePasskeyAuth(t *testing.T) { AssertHTMLElement(t, doc, ".signin-passkey", true) }) } + +func TestRequireSignInView(t *testing.T) { + defer tests.PrepareTestEnv(t)() + t.Run("NoRequireSignInView", func(t *testing.T) { + require.False(t, setting.Service.RequireSignInViewStrict) + require.False(t, setting.Service.BlockAnonymousAccessExpensive) + req := NewRequest(t, "GET", "/user2/repo1/src/branch/master") + MakeRequest(t, req, http.StatusOK) + }) + t.Run("RequireSignInView", func(t *testing.T) { + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, true)() + defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() + req := NewRequest(t, "GET", "/user2/repo1/src/branch/master") + resp := MakeRequest(t, req, http.StatusSeeOther) + assert.Equal(t, "/user/login", resp.Header().Get("Location")) + }) + t.Run("BlockAnonymousAccessExpensive", func(t *testing.T) { + defer test.MockVariableValue(&setting.Service.RequireSignInViewStrict, false)() + defer test.MockVariableValue(&setting.Service.BlockAnonymousAccessExpensive, true)() + defer test.MockVariableValue(&testWebRoutes, routers.NormalRoutes())() + + req := NewRequest(t, "GET", "/user2/repo1") + MakeRequest(t, req, http.StatusOK) + + req = NewRequest(t, "GET", "/user2/repo1/src/branch/master") + resp := MakeRequest(t, req, http.StatusSeeOther) + assert.Equal(t, "/user/login", resp.Header().Get("Location")) + }) +} diff --git a/tests/integration/ssh_key_test.go b/tests/integration/ssh_key_test.go index eb3a3e926a..fbdda9b3af 100644 --- a/tests/integration/ssh_key_test.go +++ b/tests/integration/ssh_key_test.go @@ -51,7 +51,7 @@ func testPushDeployKeyOnEmptyRepo(t *testing.T, u *url.URL) { ctx := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) ctxWithDeleteRepo := NewAPITestContext(t, "user2", "deploy-key-empty-repo-1", auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) - keyname := fmt.Sprintf("%s-push", ctx.Reponame) + keyname := ctx.Reponame + "-push" u.Path = ctx.GitPath() t.Run("CreateEmptyRepository", doAPICreateRepository(ctx, true)) @@ -89,7 +89,7 @@ func testKeyOnlyOneType(t *testing.T, u *url.URL) { reponame := "ssh-key-test-repo" username := "user2" u.Path = fmt.Sprintf("%s/%s.git", username, reponame) - keyname := fmt.Sprintf("%s-push", reponame) + keyname := reponame + "-push" // OK login ctx := NewAPITestContext(t, username, reponame, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser) diff --git a/tests/integration/user_avatar_test.go b/tests/integration/user_avatar_test.go index 7b157e6e61..14ea012ac8 100644 --- a/tests/integration/user_avatar_test.go +++ b/tests/integration/user_avatar_test.go @@ -5,7 +5,6 @@ package integration import ( "bytes" - "fmt" "image/png" "io" "mime/multipart" @@ -84,9 +83,9 @@ func TestUserAvatar(t *testing.T) { } func testGetAvatarRedirect(t *testing.T, user *user_model.User) { - t.Run(fmt.Sprintf("getAvatarRedirect_%s", user.Name), func(t *testing.T) { + t.Run("getAvatarRedirect_"+user.Name, func(t *testing.T) { req := NewRequestf(t, "GET", "/%s.png", user.Name) resp := MakeRequest(t, req, http.StatusSeeOther) - assert.EqualValues(t, fmt.Sprintf("/avatars/%s", user.Avatar), resp.Header().Get("location")) + assert.Equal(t, "/avatars/"+user.Avatar, resp.Header().Get("location")) }) } diff --git a/tests/integration/user_test.go b/tests/integration/user_test.go index fd7996bf8b..2c9a916ec2 100644 --- a/tests/integration/user_test.go +++ b/tests/integration/user_test.go @@ -217,12 +217,12 @@ func TestGetUserRss(t *testing.T) { user34 := "the_34-user.with.all.allowedChars" req := NewRequestf(t, "GET", "/%s.rss", user34) resp := MakeRequest(t, req, http.StatusOK) - if assert.EqualValues(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) { + if assert.Equal(t, "application/rss+xml;charset=utf-8", resp.Header().Get("Content-Type")) { rssDoc := NewHTMLParser(t, resp.Body).Find("channel") title, _ := rssDoc.ChildrenFiltered("title").Html() - assert.EqualValues(t, "Feed of "the_1-user.with.all.allowedChars"", title) + assert.Equal(t, "Feed of "the_1-user.with.all.allowedChars"", title) description, _ := rssDoc.ChildrenFiltered("description").Html() - assert.EqualValues(t, "<p dir="auto">some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description) + assert.Equal(t, "<p dir="auto">some <a href="https://commonmark.org/" rel="nofollow">commonmark</a>!</p>\n", description) } req = NewRequestf(t, "GET", "/non-existent-user.rss") @@ -247,11 +247,11 @@ func TestListStopWatches(t *testing.T) { 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) - assert.EqualValues(t, issue.Title, apiWatches[0].IssueTitle) - assert.EqualValues(t, repo.Name, apiWatches[0].RepoName) - assert.EqualValues(t, repo.OwnerName, apiWatches[0].RepoOwnerName) + assert.Equal(t, stopwatch.CreatedUnix.AsTime().Unix(), apiWatches[0].Created.Unix()) + assert.Equal(t, issue.Index, apiWatches[0].IssueIndex) + assert.Equal(t, issue.Title, apiWatches[0].IssueTitle) + assert.Equal(t, repo.Name, apiWatches[0].RepoName) + assert.Equal(t, repo.OwnerName, apiWatches[0].RepoOwnerName) assert.Positive(t, apiWatches[0].Seconds) } } diff --git a/tests/integration/webfinger_test.go b/tests/integration/webfinger_test.go index a1abc8d32b..2afaed4a45 100644 --- a/tests/integration/webfinger_test.go +++ b/tests/integration/webfinger_test.go @@ -7,6 +7,7 @@ import ( "fmt" "net/http" "net/url" + "strconv" "testing" "code.gitea.io/gitea/models/unittest" @@ -52,7 +53,7 @@ func TestWebfinger(t *testing.T) { var jrd webfingerJRD DecodeJSON(t, resp, &jrd) assert.Equal(t, "acct:user2@"+appURL.Host, jrd.Subject) - assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + fmt.Sprint(user.ID)}, jrd.Aliases) + assert.ElementsMatch(t, []string{user.HTMLURL(), appURL.String() + "api/v1/activitypub/user-id/" + strconv.FormatInt(user.ID, 10)}, jrd.Aliases) req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", user.LowerName, "unknown.host")) MakeRequest(t, req, http.StatusBadRequest) @@ -63,6 +64,6 @@ func TestWebfinger(t *testing.T) { req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=acct:%s@%s", "user31", appURL.Host)) session.MakeRequest(t, req, http.StatusOK) - req = NewRequest(t, "GET", fmt.Sprintf("/.well-known/webfinger?resource=mailto:%s", user.Email)) + req = NewRequest(t, "GET", "/.well-known/webfinger?resource=mailto:"+user.Email) MakeRequest(t, req, http.StatusNotFound) } diff --git a/tests/integration/wiki_test.go b/tests/integration/wiki_test.go index a571c2da50..ac458af378 100644 --- a/tests/integration/wiki_test.go +++ b/tests/integration/wiki_test.go @@ -4,7 +4,6 @@ package integration import ( - "fmt" "net/http" "net/url" "os" @@ -29,7 +28,7 @@ func assertFileExist(t *testing.T, p string) { func assertFileEqual(t *testing.T, p string, content []byte) { bs, err := os.ReadFile(p) assert.NoError(t, err) - assert.EqualValues(t, content, bs) + assert.Equal(t, content, bs) } func TestRepoCloneWiki(t *testing.T) { @@ -38,7 +37,7 @@ func TestRepoCloneWiki(t *testing.T) { dstPath := t.TempDir() - r := fmt.Sprintf("%suser2/repo1.wiki.git", u.String()) + r := u.String() + "user2/repo1.wiki.git" u, _ = url.Parse(r) u.User = url.UserPassword("user2", userPassword) t.Run("Clone", func(t *testing.T) { @@ -69,6 +68,6 @@ func Test_RepoWikiPages(t *testing.T) { href, _ := firstAnchor.Attr("href") pagePath := strings.TrimPrefix(href, "/user2/repo1/wiki/") - assert.EqualValues(t, expectedPagePaths[i], pagePath) + assert.Equal(t, expectedPagePaths[i], pagePath) }) } diff --git a/tests/integration/xss_test.go b/tests/integration/xss_test.go index a8eaa5fc62..9058fc210a 100644 --- a/tests/integration/xss_test.go +++ b/tests/integration/xss_test.go @@ -32,8 +32,8 @@ func TestXSSUserFullName(t *testing.T) { req = NewRequestf(t, "GET", "/%s", user.Name) resp := session.MakeRequest(t, req, http.StatusOK) htmlDoc := NewHTMLParser(t, resp.Body) - assert.EqualValues(t, 0, htmlDoc.doc.Find("script.evil").Length()) - assert.EqualValues(t, fullName, + assert.Equal(t, 0, htmlDoc.doc.Find("script.evil").Length()) + assert.Equal(t, fullName, htmlDoc.doc.Find("div.content").Find(".header.text.center").Text(), ) } diff --git a/tests/test_utils.go b/tests/test_utils.go index 96eb5731b4..6c95716e67 100644 --- a/tests/test_utils.go +++ b/tests/test_utils.go @@ -93,7 +93,7 @@ func InitTest(requireGitea bool) { if err != nil { log.Fatal("sql.Open: %v", err) } - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("CREATE DATABASE IF NOT EXISTS " + setting.Database.Name); err != nil { log.Fatal("db.Exec: %v", err) } case setting.Database.Type.IsPostgreSQL(): @@ -118,7 +118,7 @@ func InitTest(requireGitea bool) { defer dbrows.Close() if !dbrows.Next() { - if _, err = db.Exec(fmt.Sprintf("CREATE DATABASE %s", setting.Database.Name)); err != nil { + if _, err = db.Exec("CREATE DATABASE " + setting.Database.Name); err != nil { log.Fatal("db.Exec: CREATE DATABASE: %v", err) } } @@ -148,7 +148,7 @@ func InitTest(requireGitea bool) { if !schrows.Next() { // Create and setup a DB schema - if _, err = db.Exec(fmt.Sprintf("CREATE SCHEMA %s", setting.Database.Schema)); err != nil { + if _, err = db.Exec("CREATE SCHEMA " + setting.Database.Schema); err != nil { log.Fatal("db.Exec: CREATE SCHEMA: %v", err) } } diff --git a/web_src/css/base.css b/web_src/css/base.css index 98eb32bc13..de656c0d95 100644 --- a/web_src/css/base.css +++ b/web_src/css/base.css @@ -347,6 +347,7 @@ a.label, .ui.dropdown .menu > .item { color: var(--color-text); + line-height: var(--line-height-default); } .ui.dropdown .menu > .item:hover { @@ -646,10 +647,11 @@ img.ui.avatar, border: 1px solid; } -.ui.floating.dropdown .overflow.menu .scrolling.menu.items { +.ui.dropdown .menu.context-user-switch .scrolling.menu { border-radius: 0 !important; box-shadow: none !important; border-bottom: 1px solid var(--color-secondary); + max-width: 80vw; } .user-menu > .item { @@ -876,7 +878,6 @@ overflow-menu .ui.label { .code-inner { font: 12px var(--fonts-monospace); white-space: pre-wrap; - word-break: break-all; overflow-wrap: anywhere; line-height: inherit; /* needed for inline code preview in markup */ } @@ -1028,11 +1029,6 @@ table th[data-sortt-desc] .svg { text-align: left; } -.truncated-item-container { - display: flex !important; - align-items: center; -} - .ellipsis-button { padding: 0 5px 8px !important; display: inline-block !important; @@ -1041,15 +1037,6 @@ table th[data-sortt-desc] .svg { vertical-align: middle !important; } -.truncated-item-name { - line-height: 2; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin-top: -0.5em; - margin-bottom: -0.5em; -} - .precolors { display: flex; flex-direction: column; @@ -1166,14 +1153,20 @@ the "!important" is necessary to override Fomantic UI menu item styles, meanwhil margin: 0; /* use gap, but not margin */ } -.ui.dropdown.ellipsis-items-nowrap > .text { +.ui.dropdown.ellipsis-text-items { + /* reset y padding and use the line-height below instead, to avoid the "overflow: hidden" clips the larger image in the "text" element */ + padding-top: 0; + padding-bottom: 0; +} + +.ui.dropdown.ellipsis-text-items > .text { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; + line-height: 2.71; /* matches fomantic dropdown's default min-height */ } -.ellipsis-items-nowrap > .item, -.ui.dropdown.ellipsis-items-nowrap .menu > .item { +.ui.dropdown.ellipsis-text-items .menu > .item { white-space: nowrap !important; overflow: hidden !important; text-overflow: ellipsis !important; diff --git a/web_src/css/markup/content.css b/web_src/css/markup/content.css index 6d985a76a7..937224a9d7 100644 --- a/web_src/css/markup/content.css +++ b/web_src/css/markup/content.css @@ -2,11 +2,7 @@ overflow: hidden; font-size: 16px; line-height: 1.5 !important; - overflow-wrap: break-word; -} - -.conversation-holder .markup { - overflow-wrap: anywhere; /* prevent overflow in code comments. TODO: properly restrict .conversation-holder width and remove this */ + overflow-wrap: anywhere; } .markup > *:first-child { @@ -451,8 +447,7 @@ margin: 0; font-size: 100%; white-space: pre-wrap; - word-break: break-all; - overflow-wrap: break-word; + overflow-wrap: anywhere; background: transparent; border: 0; } @@ -515,6 +510,18 @@ padding-left: 2em; } +.markup details.frontmatter-content summary { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + margin-bottom: 0.25em; +} + +.markup details.frontmatter-content svg { + vertical-align: middle; + margin: 0 0.25em; +} + .file-revisions-btn { display: block; float: left; diff --git a/web_src/css/repo.css b/web_src/css/repo.css index 87af299dad..db44e2a778 100644 --- a/web_src/css/repo.css +++ b/web_src/css/repo.css @@ -1724,8 +1724,7 @@ tbody.commit-list { line-height: 18px; margin: 1em; white-space: pre-wrap; - word-break: break-all; - overflow-wrap: break-word; + overflow-wrap: anywhere; } .content-history-detail-dialog .header .avatar { diff --git a/web_src/js/components/RepoActionView.vue b/web_src/js/components/RepoActionView.vue index 2ef528620d..640ad8341f 100644 --- a/web_src/js/components/RepoActionView.vue +++ b/web_src/js/components/RepoActionView.vue @@ -955,7 +955,6 @@ export default defineComponent({ .job-step-logs .job-log-line .log-msg { flex: 1; - word-break: break-all; white-space: break-spaces; margin-left: 10px; overflow-wrap: anywhere; diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue index 820e69d9ab..99ccdfaa6d 100644 --- a/web_src/js/components/RepoBranchTagSelector.vue +++ b/web_src/js/components/RepoBranchTagSelector.vue @@ -216,7 +216,7 @@ export default defineComponent({ }); - + {{ dropdownFixedText }} diff --git a/web_src/js/components/ViewFileTree.vue b/web_src/js/components/ViewFileTree.vue index 1820c47e7a..c692142792 100644 --- a/web_src/js/components/ViewFileTree.vue +++ b/web_src/js/components/ViewFileTree.vue @@ -3,6 +3,7 @@ import ViewFileTreeItem from './ViewFileTreeItem.vue'; import {onMounted, ref} from 'vue'; import {pathEscapeSegments} from '../utils/url.ts'; import {GET} from '../modules/fetch.ts'; +import {createElementFromHTML} from '../utils/dom.ts'; const elRoot = ref(null); @@ -18,6 +19,15 @@ const selectedItem = ref(''); async function loadChildren(treePath: string, subPath: string = '') { const response = await GET(`${props.repoLink}/tree-view/${props.currentRefNameSubURL}/${pathEscapeSegments(treePath)}?sub_path=${encodeURIComponent(subPath)}`); const json = await response.json(); + const poolSvgs = []; + for (const [svgId, svgContent] of Object.entries(json.renderedIconPool ?? {})) { + if (!document.querySelector(`.global-svg-icon-pool #${svgId}`)) poolSvgs.push(svgContent); + } + if (poolSvgs.length) { + const svgContainer = createElementFromHTML(''); + svgContainer.innerHTML = poolSvgs.join(''); + document.body.append(svgContainer); + } return json.fileTreeNodes ?? null; } diff --git a/web_src/js/components/ViewFileTreeItem.vue b/web_src/js/components/ViewFileTreeItem.vue index 4dffc86a1b..69e26dbc33 100644 --- a/web_src/js/components/ViewFileTreeItem.vue +++ b/web_src/js/components/ViewFileTreeItem.vue @@ -5,6 +5,8 @@ import {ref} from 'vue'; type Item = { entryName: string; entryMode: string; + entryIcon: string; + entryIconOpen: string; fullPath: string; submoduleUrl?: string; children?: Item[]; @@ -80,7 +82,8 @@ const doGotoSubModule = () => { > - + + {{ item.entryName }} @@ -92,11 +95,13 @@ const doGotoSubModule = () => { > + - + + {{ item.entryName }} diff --git a/web_src/js/features/repo-commit.ts b/web_src/js/features/repo-commit.ts index e6d1112778..98ec2328ec 100644 --- a/web_src/js/features/repo-commit.ts +++ b/web_src/js/features/repo-commit.ts @@ -1,6 +1,6 @@ import {createTippy} from '../modules/tippy.ts'; import {toggleElem} from '../utils/dom.ts'; -import {registerGlobalEventFunc} from '../modules/observer.ts'; +import {registerGlobalEventFunc, registerGlobalInitFunc} from '../modules/observer.ts'; export function initRepoEllipsisButton() { registerGlobalEventFunc('click', 'onRepoEllipsisButtonClick', async (el: HTMLInputElement, e: Event) => { @@ -12,15 +12,15 @@ export function initRepoEllipsisButton() { } export function initCommitStatuses() { - for (const element of document.querySelectorAll('[data-tippy="commit-statuses"]')) { - const top = document.querySelector('.repository.file.list') || document.querySelector('.repository.diff'); - - createTippy(element, { - content: element.nextElementSibling, - placement: top ? 'top-start' : 'bottom-start', + registerGlobalInitFunc('initCommitStatuses', (el: HTMLElement) => { + const nextEl = el.nextElementSibling; + if (!nextEl.matches('.tippy-target')) throw new Error('Expected next element to be a tippy target'); + createTippy(el, { + content: nextEl, + placement: 'bottom-start', interactive: true, role: 'dialog', theme: 'box-with-header', }); - } + }); } diff --git a/web_src/js/features/repo-settings.ts b/web_src/js/features/repo-settings.ts index 80f897069e..27dc4e9bfe 100644 --- a/web_src/js/features/repo-settings.ts +++ b/web_src/js/features/repo-settings.ts @@ -1,6 +1,6 @@ import {minimatch} from 'minimatch'; import {createMonaco} from './codeeditor.ts'; -import {onInputDebounce, queryElems, toggleElem} from '../utils/dom.ts'; +import {onInputDebounce, queryElems, toggleClass, toggleElem} from '../utils/dom.ts'; import {POST} from '../modules/fetch.ts'; import {initAvatarUploaderWithCropper} from './comp/Cropper.ts'; import {initRepoSettingsBranchesDrag} from './repo-settings-branches.ts'; @@ -125,22 +125,14 @@ function initRepoSettingsOptions() { const pageContent = document.querySelector('.page-content.repository.settings.options'); if (!pageContent) return; - const toggleClass = (elems: NodeListOf, className: string, value: boolean) => { - for (const el of elems) el.classList.toggle(className, value); - }; - // Enable or select internal/external wiki system and issue tracker. queryElems(pageContent, '.enable-system', (el) => el.addEventListener('change', () => { - const elTargets = document.querySelectorAll(el.getAttribute('data-target')); - const elContexts = document.querySelectorAll(el.getAttribute('data-context')); - toggleClass(elTargets, 'disabled', !el.checked); - toggleClass(elContexts, 'disabled', el.checked); + toggleClass(el.getAttribute('data-target'), 'disabled', !el.checked); + toggleClass(el.getAttribute('data-context'), 'disabled', el.checked); })); queryElems(pageContent, '.enable-system-radio', (el) => el.addEventListener('change', () => { - const elTargets = document.querySelectorAll(el.getAttribute('data-target')); - const elContexts = document.querySelectorAll(el.getAttribute('data-context')); - toggleClass(elTargets, 'disabled', el.value === 'false'); - toggleClass(elContexts, 'disabled', el.value === 'true'); + toggleClass(el.getAttribute('data-target'), 'disabled', el.value === 'false'); + toggleClass(el.getAttribute('data-context'), 'disabled', el.value === 'true'); })); queryElems(pageContent, '.js-tracker-issue-style', (el) => el.addEventListener('change', () => { diff --git a/web_src/js/markup/asciicast.ts b/web_src/js/markup/asciicast.ts index 22dbff2d46..125bba447b 100644 --- a/web_src/js/markup/asciicast.ts +++ b/web_src/js/markup/asciicast.ts @@ -1,16 +1,17 @@ +import {queryElems} from '../utils/dom.ts'; + export async function initMarkupRenderAsciicast(elMarkup: HTMLElement): Promise { - const el = elMarkup.querySelector('.asciinema-player-container'); - if (!el) return; + queryElems(elMarkup, '.asciinema-player-container', async (el) => { + const [player] = await Promise.all([ + // @ts-expect-error: module exports no types + import(/* webpackChunkName: "asciinema-player" */'asciinema-player'), + import(/* webpackChunkName: "asciinema-player" */'asciinema-player/dist/bundle/asciinema-player.css'), + ]); - const [player] = await Promise.all([ - // @ts-expect-error: module exports no types - import(/* webpackChunkName: "asciinema-player" */'asciinema-player'), - import(/* webpackChunkName: "asciinema-player" */'asciinema-player/dist/bundle/asciinema-player.css'), - ]); - - player.create(el.getAttribute('data-asciinema-player-src'), el, { - // poster (a preview frame) to display until the playback is started. - // Set it to 1 hour (also means the end if the video is shorter) to make the preview frame show more. - poster: 'npt:1:0:0', + player.create(el.getAttribute('data-asciinema-player-src'), el, { + // poster (a preview frame) to display until the playback is started. + // Set it to 1 hour (also means the end if the video is shorter) to make the preview frame show more. + poster: 'npt:1:0:0', + }); }); } diff --git a/web_src/js/markup/codecopy.ts b/web_src/js/markup/codecopy.ts index 4430256848..67284bad55 100644 --- a/web_src/js/markup/codecopy.ts +++ b/web_src/js/markup/codecopy.ts @@ -1,4 +1,5 @@ import {svg} from '../svg.ts'; +import {queryElems} from '../utils/dom.ts'; export function makeCodeCopyButton(): HTMLButtonElement { const button = document.createElement('button'); @@ -8,11 +9,12 @@ export function makeCodeCopyButton(): HTMLButtonElement { } export function initMarkupCodeCopy(elMarkup: HTMLElement): void { - const el = elMarkup.querySelector('.code-block code'); // .markup .code-block code - if (!el || !el.textContent) return; - - const btn = makeCodeCopyButton(); - // remove final trailing newline introduced during HTML rendering - btn.setAttribute('data-clipboard-text', el.textContent.replace(/\r?\n$/, '')); - el.after(btn); + // .markup .code-block code + queryElems(elMarkup, '.code-block code', (el) => { + if (!el.textContent) return; + const btn = makeCodeCopyButton(); + // remove final trailing newline introduced during HTML rendering + btn.setAttribute('data-clipboard-text', el.textContent.replace(/\r?\n$/, '')); + el.after(btn); + }); } diff --git a/web_src/js/markup/math.ts b/web_src/js/markup/math.ts index 2a4468bf2e..bc118137a1 100644 --- a/web_src/js/markup/math.ts +++ b/web_src/js/markup/math.ts @@ -1,4 +1,5 @@ import {displayError} from './common.ts'; +import {queryElems} from '../utils/dom.ts'; function targetElement(el: Element): {target: Element, displayAsBlock: boolean} { // The target element is either the parent "code block with loading indicator", or itself @@ -12,35 +13,35 @@ function targetElement(el: Element): {target: Element, displayAsBlock: boolean} } export async function initMarkupCodeMath(elMarkup: HTMLElement): Promise { - const el = elMarkup.querySelector('code.language-math'); // .markup code.language-math' - if (!el) return; + // .markup code.language-math' + queryElems(elMarkup, 'code.language-math', async (el) => { + const [{default: katex}] = await Promise.all([ + import(/* webpackChunkName: "katex" */'katex'), + import(/* webpackChunkName: "katex" */'katex/dist/katex.css'), + ]); - const [{default: katex}] = await Promise.all([ - import(/* webpackChunkName: "katex" */'katex'), - import(/* webpackChunkName: "katex" */'katex/dist/katex.css'), - ]); + const MAX_CHARS = 1000; + const MAX_SIZE = 25; + const MAX_EXPAND = 1000; - const MAX_CHARS = 1000; - const MAX_SIZE = 25; - const MAX_EXPAND = 1000; + const {target, displayAsBlock} = targetElement(el); + if (target.hasAttribute('data-render-done')) return; + const source = el.textContent; - const {target, displayAsBlock} = targetElement(el); - if (target.hasAttribute('data-render-done')) return; - const source = el.textContent; - - if (source.length > MAX_CHARS) { - displayError(target, new Error(`Math source of ${source.length} characters exceeds the maximum allowed length of ${MAX_CHARS}.`)); - return; - } - try { - const tempEl = document.createElement(displayAsBlock ? 'p' : 'span'); - katex.render(source, tempEl, { - maxSize: MAX_SIZE, - maxExpand: MAX_EXPAND, - displayMode: displayAsBlock, // katex: true for display (block) mode, false for inline mode - }); - target.replaceWith(tempEl); - } catch (error) { - displayError(target, error); - } + if (source.length > MAX_CHARS) { + displayError(target, new Error(`Math source of ${source.length} characters exceeds the maximum allowed length of ${MAX_CHARS}.`)); + return; + } + try { + const tempEl = document.createElement(displayAsBlock ? 'p' : 'span'); + katex.render(source, tempEl, { + maxSize: MAX_SIZE, + maxExpand: MAX_EXPAND, + displayMode: displayAsBlock, // katex: true for display (block) mode, false for inline mode + }); + target.replaceWith(tempEl); + } catch (error) { + displayError(target, error); + } + }); } diff --git a/web_src/js/markup/mermaid.ts b/web_src/js/markup/mermaid.ts index b4bf3153ea..ac24b3bcba 100644 --- a/web_src/js/markup/mermaid.ts +++ b/web_src/js/markup/mermaid.ts @@ -1,6 +1,7 @@ import {isDarkTheme} from '../utils.ts'; import {makeCodeCopyButton} from './codecopy.ts'; import {displayError} from './common.ts'; +import {queryElems} from '../utils/dom.ts'; const {mermaidMaxSourceCharacters} = window.config; @@ -11,77 +12,77 @@ body {margin: 0; padding: 0; overflow: hidden} blockquote, dd, dl, figure, h1, h2, h3, h4, h5, h6, hr, p, pre {margin: 0}`; export async function initMarkupCodeMermaid(elMarkup: HTMLElement): Promise { - const el = elMarkup.querySelector('code.language-mermaid'); // .markup code.language-mermaid - if (!el) return; + // .markup code.language-mermaid + queryElems(elMarkup, 'code.language-mermaid', async (el) => { + const {default: mermaid} = await import(/* webpackChunkName: "mermaid" */'mermaid'); - const {default: mermaid} = await import(/* webpackChunkName: "mermaid" */'mermaid'); - - mermaid.initialize({ - startOnLoad: false, - theme: isDarkTheme() ? 'dark' : 'neutral', - securityLevel: 'strict', - suppressErrorRendering: true, - }); - - const pre = el.closest('pre'); - if (pre.hasAttribute('data-render-done')) return; - - const source = el.textContent; - if (mermaidMaxSourceCharacters >= 0 && source.length > mermaidMaxSourceCharacters) { - displayError(pre, new Error(`Mermaid source of ${source.length} characters exceeds the maximum allowed length of ${mermaidMaxSourceCharacters}.`)); - return; - } - - try { - await mermaid.parse(source); - } catch (err) { - displayError(pre, err); - return; - } - - try { - // can't use bindFunctions here because we can't cross the iframe boundary. This - // means js-based interactions won't work but they aren't intended to work either - const {svg} = await mermaid.render('mermaid', source); - - const iframe = document.createElement('iframe'); - iframe.classList.add('markup-content-iframe', 'tw-invisible'); - iframe.srcdoc = `${svg}`; - - const mermaidBlock = document.createElement('div'); - mermaidBlock.classList.add('mermaid-block', 'is-loading', 'tw-hidden'); - mermaidBlock.append(iframe); - - const btn = makeCodeCopyButton(); - btn.setAttribute('data-clipboard-text', source); - mermaidBlock.append(btn); - - const updateIframeHeight = () => { - const body = iframe.contentWindow?.document?.body; - if (body) { - iframe.style.height = `${body.clientHeight}px`; - } - }; - - iframe.addEventListener('load', () => { - pre.replaceWith(mermaidBlock); - mermaidBlock.classList.remove('tw-hidden'); - updateIframeHeight(); - setTimeout(() => { // avoid flash of iframe background - mermaidBlock.classList.remove('is-loading'); - iframe.classList.remove('tw-invisible'); - }, 0); - - // update height when element's visibility state changes, for example when the diagram is inside - // a + block and the block becomes visible upon user interaction, it - // would initially set a incorrect height and the correct height is set during this callback. - (new IntersectionObserver(() => { - updateIframeHeight(); - }, {root: document.documentElement})).observe(iframe); + mermaid.initialize({ + startOnLoad: false, + theme: isDarkTheme() ? 'dark' : 'neutral', + securityLevel: 'strict', + suppressErrorRendering: true, }); - document.body.append(mermaidBlock); - } catch (err) { - displayError(pre, err); - } + const pre = el.closest('pre'); + if (pre.hasAttribute('data-render-done')) return; + + const source = el.textContent; + if (mermaidMaxSourceCharacters >= 0 && source.length > mermaidMaxSourceCharacters) { + displayError(pre, new Error(`Mermaid source of ${source.length} characters exceeds the maximum allowed length of ${mermaidMaxSourceCharacters}.`)); + return; + } + + try { + await mermaid.parse(source); + } catch (err) { + displayError(pre, err); + return; + } + + try { + // can't use bindFunctions here because we can't cross the iframe boundary. This + // means js-based interactions won't work but they aren't intended to work either + const {svg} = await mermaid.render('mermaid', source); + + const iframe = document.createElement('iframe'); + iframe.classList.add('markup-content-iframe', 'tw-invisible'); + iframe.srcdoc = `${svg}`; + + const mermaidBlock = document.createElement('div'); + mermaidBlock.classList.add('mermaid-block', 'is-loading', 'tw-hidden'); + mermaidBlock.append(iframe); + + const btn = makeCodeCopyButton(); + btn.setAttribute('data-clipboard-text', source); + mermaidBlock.append(btn); + + const updateIframeHeight = () => { + const body = iframe.contentWindow?.document?.body; + if (body) { + iframe.style.height = `${body.clientHeight}px`; + } + }; + + iframe.addEventListener('load', () => { + pre.replaceWith(mermaidBlock); + mermaidBlock.classList.remove('tw-hidden'); + updateIframeHeight(); + setTimeout(() => { // avoid flash of iframe background + mermaidBlock.classList.remove('is-loading'); + iframe.classList.remove('tw-invisible'); + }, 0); + + // update height when element's visibility state changes, for example when the diagram is inside + // a + block and the block becomes visible upon user interaction, it + // would initially set a incorrect height and the correct height is set during this callback. + (new IntersectionObserver(() => { + updateIframeHeight(); + }, {root: document.documentElement})).observe(iframe); + }); + + document.body.append(mermaidBlock); + } catch (err) { + displayError(pre, err); + } + }); } diff --git a/web_src/js/utils/dom.test.ts b/web_src/js/utils/dom.test.ts index 6e71596850..6a3af91556 100644 --- a/web_src/js/utils/dom.test.ts +++ b/web_src/js/utils/dom.test.ts @@ -1,4 +1,10 @@ -import {createElementFromAttrs, createElementFromHTML, queryElemChildren, querySingleVisibleElem} from './dom.ts'; +import { + createElementFromAttrs, + createElementFromHTML, + queryElemChildren, + querySingleVisibleElem, + toggleElem, +} from './dom.ts'; test('createElementFromHTML', () => { expect(createElementFromHTML('foobar').outerHTML).toEqual('foobar'); @@ -32,3 +38,13 @@ test('queryElemChildren', () => { const children = queryElemChildren(el, '.a'); expect(children.length).toEqual(1); }); + +test('toggleElem', () => { + const el = createElementFromHTML('ab'); + toggleElem(el.children); + expect(el.outerHTML).toEqual('ab'); + toggleElem(el.children, false); + expect(el.outerHTML).toEqual('ab'); + toggleElem(el.children, true); + expect(el.outerHTML).toEqual('ab'); +}); diff --git a/web_src/js/utils/dom.ts b/web_src/js/utils/dom.ts index 4d15784e6e..b3debfde9e 100644 --- a/web_src/js/utils/dom.ts +++ b/web_src/js/utils/dom.ts @@ -25,32 +25,34 @@ function elementsCall(el: ElementArg, func: ElementsCallbackWithArgs, ...args: a } } +export function toggleClass(el: ElementArg, className: string, force?: boolean) { + elementsCall(el, (e: Element) => { + if (force === true) { + e.classList.add(className); + } else if (force === false) { + e.classList.remove(className); + } else if (force === undefined) { + e.classList.toggle(className); + } else { + throw new Error('invalid force argument'); + } + }); +} + /** - * @param el Element + * @param el ElementArg * @param force force=true to show or force=false to hide, undefined to toggle */ -function toggleShown(el: Element, force: boolean) { - if (force === true) { - el.classList.remove('tw-hidden'); - } else if (force === false) { - el.classList.add('tw-hidden'); - } else if (force === undefined) { - el.classList.toggle('tw-hidden'); - } else { - throw new Error('invalid force argument'); - } +export function toggleElem(el: ElementArg, force?: boolean) { + toggleClass(el, 'tw-hidden', force === undefined ? force : !force); } export function showElem(el: ElementArg) { - elementsCall(el, toggleShown, true); + toggleElem(el, true); } export function hideElem(el: ElementArg) { - elementsCall(el, toggleShown, false); -} - -export function toggleElem(el: ElementArg, force?: boolean) { - elementsCall(el, toggleShown, force); + toggleElem(el, false); } export function isElemHidden(el: ElementArg) {
d8a994ef24
d8a994ef24 (diff-2)
#12345
65f1bf27bc
65f1bf2
65f1bf27bc/src
65f1bf27bc...65f1bf27bc
65f1bf27bc...65f1bf27bc (L2)
commit 65f1bf27bc
/home/gitea/"+sha+"
deadbeef
d27ace93
`+sha[:14]+`.x
` + sha[:10] + `
`+expected14+`.
`+expected14+`,
[`+expected14+`]
test-owner/test-repo#12345
go-gitea/gitea#12345
/home/gitea/go-gitea/gitea#12345
783b039...da951ce
a
$a$
(a)
$$ +a +$$
+a +
[ +a +]
-
+
test
link1 +link2 +link3
https://google.com/
The Image Desc
Test
88fc37a3c0...12fc37a3c0 (hash)
88fc37a3c0
@no-such-user @mention-user @mention-user
Here are some links to the most important topics. You can find the full list of pages at the sidebar.
Configuration -
Link -
{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DefaultBranchBranch.DBBranch.CommitTime}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}
{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DefaultBranchBranch.DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DefaultBranchBranch.DBBranch.CommitMessage (.Repository.ComposeCommentMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DefaultBranchBranch.DBBranch.CommitTime}}{{if .DefaultBranchBranch.DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DefaultBranchBranch.DBBranch.Pusher}}{{template "shared/user/namelink" .DefaultBranchBranch.DBBranch.Pusher}}{{end}}
{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DBBranch.CommitMessage ($.Repository.ComposeMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DBBranch.CommitTime}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}
{{svg "octicon-git-commit" 16 "tw-mr-1"}}{{ShortSha .DBBranch.CommitID}} · {{ctx.RenderUtils.RenderCommitMessage .DBBranch.CommitMessage ($.Repository.ComposeCommentMetas ctx)}} · {{ctx.Locale.Tr "org.repo_updated"}} {{DateUtils.TimeSince .DBBranch.CommitTime}}{{if .DBBranch.Pusher}} {{template "shared/user/avatarlink" dict "user" .DBBranch.Pusher}} {{template "shared/user/namelink" .DBBranch.Pusher}}{{end}}
{{ctx.RenderUtils.RenderCommitBody .Commit.Message ($.Repository.ComposeMetas ctx)}}
{{ctx.RenderUtils.RenderCommitBody .Commit.Message ($.Repository.ComposeCommentMetas ctx)}}
{{ctx.RenderUtils.RenderCommitBody .Message ($.Repository.ComposeMetas ctx)}}
{{ctx.RenderUtils.RenderCommitBody .Message ($.Repository.ComposeCommentMetas ctx)}}
- {{- ctx.RenderUtils.RenderCommitBody .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeMetas ctx) -}} + {{- ctx.RenderUtils.RenderCommitBody .Message ($.comment.Issue.PullRequest.BaseRepo.ComposeCommentMetas ctx) -}}
{{ctx.RenderUtils.RenderCommitBody .LatestCommit.Message ($.Repository.ComposeMetas ctx)}}
{{ctx.RenderUtils.RenderCommitBody .LatestCommit.Message ($.Repository.ComposeCommentMetas ctx)}}
{{ctx.Locale.Tr "error.occurred"}}:
{{.ErrorMsg}}