diff --git a/cmd/gogs/cert.go b/cmd/gogs/cert.go index 5d7665ad8..01092dc46 100644 --- a/cmd/gogs/cert.go +++ b/cmd/gogs/cert.go @@ -121,8 +121,8 @@ func runCert(ctx *cli.Context) error { BasicConstraintsValid: true, } - hosts := strings.Split(ctx.String("host"), ",") - for _, h := range hosts { + hosts := strings.SplitSeq(ctx.String("host"), ",") + for h := range hosts { if ip := net.ParseIP(h); ip != nil { template.IPAddresses = append(template.IPAddresses, ip) } else { diff --git a/internal/auth/smtp/provider.go b/internal/auth/smtp/provider.go index b9aa6bed0..01d33d6cb 100644 --- a/internal/auth/smtp/provider.go +++ b/internal/auth/smtp/provider.go @@ -3,6 +3,7 @@ package smtp import ( "net/smtp" "net/textproto" + "slices" "strings" "github.com/cockroachdb/errors" @@ -34,13 +35,7 @@ func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, } domain := fields[1] - isAllowed := false - for _, allowed := range strings.Split(p.config.AllowedDomains, ",") { - if domain == allowed { - isAllowed = true - break - } - } + isAllowed := slices.Contains(strings.Split(p.config.AllowedDomains, ","), domain) if !isAllowed { return nil, auth.ErrBadCredentials{Args: map[string]any{"login": login}} @@ -72,9 +67,9 @@ func (p *Provider) Authenticate(login, password string) (*auth.ExternalAccount, username := login // NOTE: It is not required to have "@" in `login` for a successful SMTP authentication. - idx := strings.Index(login, "@") - if idx > -1 { - username = login[:idx] + before, _, ok := strings.Cut(login, "@") + if ok { + username = before } return &auth.ExternalAccount{ diff --git a/internal/context/repo.go b/internal/context/repo.go index 75d07300a..d9708ed3a 100644 --- a/internal/context/repo.go +++ b/internal/context/repo.go @@ -178,17 +178,16 @@ func RepoAssignment(pages ...bool) macaron.Handler { // If the authenticated user has no direct access, see if the repository is a fork // and whether the user has access to the base repository. if c.Repo.AccessMode == database.AccessModeNone && repo.BaseRepo != nil { - mode := database.Handle.Permissions().AccessMode(c.Req.Context(), c.UserID(), repo.BaseRepo.ID, - database.AccessModeOptions{ - OwnerID: repo.BaseRepo.OwnerID, - Private: repo.BaseRepo.IsPrivate, - }, + mode := min( + // Users shouldn't have indirect access level higher than write. + database.Handle.Permissions().AccessMode(c.Req.Context(), c.UserID(), repo.BaseRepo.ID, + database.AccessModeOptions{ + OwnerID: repo.BaseRepo.OwnerID, + Private: repo.BaseRepo.IsPrivate, + }, + ), + database.AccessModeWrite, ) - - // Users shouldn't have indirect access level higher than write. - if mode > database.AccessModeWrite { - mode = database.AccessModeWrite - } c.Repo.AccessMode = mode } diff --git a/internal/database/issue.go b/internal/database/issue.go index f55fda552..6746934f6 100644 --- a/internal/database/issue.go +++ b/internal/database/issue.go @@ -741,7 +741,7 @@ func newIssue(e *xorm.Session, opts NewIssueOptions) (err error) { return errors.Newf("getAttachmentsByUUIDs [uuids: %v]: %v", opts.Attachments, err) } - for i := 0; i < len(attachments); i++ { + for i := range attachments { attachments[i].IssueID = opts.Issue.ID if _, err = e.ID(attachments[i].ID).Update(attachments[i]); err != nil { return errors.Newf("update attachment [id: %d]: %v", attachments[i].ID, err) @@ -823,17 +823,17 @@ func (ErrIssueNotExist) NotFound() bool { // GetIssueByRef returns an Issue specified by a GFM reference, e.g. owner/repo#123. func GetIssueByRef(ref string) (*Issue, error) { - n := strings.IndexByte(ref, byte('#')) - if n == -1 { + before, after, ok := strings.Cut(ref, "#") + if !ok { return nil, ErrIssueNotExist{args: map[string]any{"ref": ref}} } - index := com.StrTo(ref[n+1:]).MustInt64() + index := com.StrTo(after).MustInt64() if index == 0 { return nil, ErrIssueNotExist{args: map[string]any{"ref": ref}} } - repo, err := GetRepositoryByRef(ref[:n]) + repo, err := GetRepositoryByRef(before) if err != nil { return nil, err } diff --git a/internal/database/issue_label.go b/internal/database/issue_label.go index 58d2c71bd..5f4dc6f73 100644 --- a/internal/database/issue_label.go +++ b/internal/database/issue_label.go @@ -28,7 +28,7 @@ func GetLabelTemplateFile(name string) ([][2]string, error) { lines := strings.Split(string(data), "\n") list := make([][2]string, 0, len(lines)) - for i := 0; i < len(lines); i++ { + for i := range lines { line := strings.TrimSpace(lines[i]) if line == "" { continue diff --git a/internal/database/repo.go b/internal/database/repo.go index 77385c9d0..c8e21f85a 100644 --- a/internal/database/repo.go +++ b/internal/database/repo.go @@ -909,7 +909,7 @@ func createDelegateHooks(repoPath string) (err error) { for _, name := range git.ServerSideHooks { hookPath := filepath.Join(repoPath, "hooks", string(name)) if err = os.WriteFile(hookPath, - []byte(fmt.Sprintf(hooksTpls[name], conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf)), + fmt.Appendf(nil, hooksTpls[name], conf.Repository.ScriptType, conf.AppPath(), conf.CustomConf), os.ModePerm); err != nil { return errors.Newf("create delegate hook '%s': %v", hookPath, err) } @@ -1016,8 +1016,8 @@ func prepareRepoCommit(repo *Repository, tmpDir, repoPath string, opts CreateRep // .gitignore if len(opts.Gitignores) > 0 { var buf bytes.Buffer - names := strings.Split(opts.Gitignores, ",") - for _, name := range names { + names := strings.SplitSeq(opts.Gitignores, ",") + for name := range names { data, err = getRepoInitFile("gitignore", name) if err != nil { return errors.Newf("getRepoInitFile[%s]: %v", name, err) diff --git a/internal/database/repo_editor.go b/internal/database/repo_editor.go index 44bc64e52..3d5191ab0 100644 --- a/internal/database/repo_editor.go +++ b/internal/database/repo_editor.go @@ -482,7 +482,7 @@ func DeleteUploads(uploads ...*Upload) (err error) { } ids := make([]int64, len(uploads)) - for i := 0; i < len(uploads); i++ { + for i := range uploads { ids[i] = uploads[i].ID } if _, err = sess.In("id", ids).Delete(new(Upload)); err != nil { diff --git a/internal/database/schemadoc/main.go b/internal/database/schemadoc/main.go index 4b75a874d..3473f723c 100644 --- a/internal/database/schemadoc/main.go +++ b/internal/database/schemadoc/main.go @@ -22,7 +22,7 @@ import ( "gogs.io/gogs/internal/database" ) -//go:generate go run main.go ../../../docs/dev/database_schema.md +//go:generate go run main.go ../../../docs-old/dev/database_schema.md func main() { w, err := os.Create(os.Args[1]) diff --git a/internal/database/two_factors.go b/internal/database/two_factors.go index 9469dc4d0..d95354267 100644 --- a/internal/database/two_factors.go +++ b/internal/database/two_factors.go @@ -135,7 +135,7 @@ func (s *TwoFactorsStore) UseRecoveryCode(ctx context.Context, userID int64, cod // generateRecoveryCodes generates N number of recovery codes for 2FA. func generateRecoveryCodes(userID int64, n int) ([]*TwoFactorRecoveryCode, error) { recoveryCodes := make([]*TwoFactorRecoveryCode, n) - for i := 0; i < n; i++ { + for i := range n { code, err := strutil.RandomChars(10) if err != nil { return nil, errors.Wrap(err, "generate random characters") diff --git a/internal/database/webhook_dingtalk.go b/internal/database/webhook_dingtalk.go index 50e40ae2a..fc778cf13 100644 --- a/internal/database/webhook_dingtalk.go +++ b/internal/database/webhook_dingtalk.go @@ -129,11 +129,11 @@ func getDingtalkPushPayload(p *api.PushPayload) *DingtalkPayload { pusher = p.Pusher.UserName } - var detail string + var detail strings.Builder for i, commit := range p.Commits { msg := strings.Split(commit.Message, "\n")[0] commitLink := MarkdownLinkFormatter(commit.URL, commit.ID[:7]) - detail += fmt.Sprintf("> %d. %s %s - %s\n", i, commitLink, commit.Author.Name, msg) + detail.WriteString(fmt.Sprintf("> %d. %s %s - %s\n", i, commitLink, commit.Author.Name, msg)) } actionCard := NewDingtalkActionCard("View Changes", p.CompareURL) @@ -142,7 +142,7 @@ func getDingtalkPushPayload(p *api.PushPayload) *DingtalkPayload { actionCard.Text += "\n- Ref: **" + MarkdownLinkFormatter(p.Repo.HTMLURL+"/src/"+refName, refName) + "**" actionCard.Text += "\n- Pusher: **" + pusher + "**" actionCard.Text += "\n## " + fmt.Sprintf("Total %d commits(s)", len(p.Commits)) - actionCard.Text += "\n" + detail + actionCard.Text += "\n" + detail.String() return &DingtalkPayload{ MsgType: "actionCard", diff --git a/internal/database/webhook_discord.go b/internal/database/webhook_discord.go index b11550d46..a804bccb6 100644 --- a/internal/database/webhook_discord.go +++ b/internal/database/webhook_discord.go @@ -140,14 +140,15 @@ func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) *DiscordPayload repoLink := DiscordLinkFormatter(p.Repo.HTMLURL, p.Repo.Name) branchLink := DiscordLinkFormatter(p.Repo.HTMLURL+"/src/"+branchName, branchName) - content := fmt.Sprintf("Pushed %s to %s/%s\n", commitString, repoLink, branchLink) + var content strings.Builder + content.WriteString(fmt.Sprintf("Pushed %s to %s/%s\n", commitString, repoLink, branchLink)) // for each commit, generate attachment text for i, commit := range p.Commits { - content += fmt.Sprintf("%s %s - %s", DiscordSHALinkFormatter(commit.URL, commit.ID[:7]), DiscordTextFormatter(commit.Message), commit.Author.Name) + content.WriteString(fmt.Sprintf("%s %s - %s", DiscordSHALinkFormatter(commit.URL, commit.ID[:7]), DiscordTextFormatter(commit.Message), commit.Author.Name)) // add linebreak to each commit but the last if i < len(p.Commits)-1 { - content += "\n" + content.WriteString("\n") } } @@ -156,7 +157,7 @@ func getDiscordPushPayload(p *api.PushPayload, slack *SlackMeta) *DiscordPayload Username: slack.Username, AvatarURL: slack.IconURL, Embeds: []*DiscordEmbedObject{{ - Description: content, + Description: content.String(), URL: conf.Server.ExternalURL + p.Sender.UserName, Color: int(color), Author: &DiscordEmbedAuthorObject{ diff --git a/internal/database/webhook_slack.go b/internal/database/webhook_slack.go index 13c5a5e46..6348b3374 100644 --- a/internal/database/webhook_slack.go +++ b/internal/database/webhook_slack.go @@ -121,13 +121,13 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) *SlackPayload { branchLink := SlackLinkFormatter(p.Repo.HTMLURL+"/src/"+branchName, branchName) text := fmt.Sprintf("[%s:%s] %s pushed by %s", repoLink, branchLink, commitString, p.Pusher.UserName) - var attachmentText string + var attachmentText strings.Builder // for each commit, generate attachment text for i, commit := range p.Commits { - attachmentText += fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.URL, commit.ID[:7]), SlackShortTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name)) + attachmentText.WriteString(fmt.Sprintf("%s: %s - %s", SlackLinkFormatter(commit.URL, commit.ID[:7]), SlackShortTextFormatter(commit.Message), SlackTextFormatter(commit.Author.Name))) // add linebreak to each commit but the last if i < len(p.Commits)-1 { - attachmentText += "\n" + attachmentText.WriteString("\n") } } @@ -138,7 +138,7 @@ func getSlackPushPayload(p *api.PushPayload, slack *SlackMeta) *SlackPayload { IconURL: slack.IconURL, Attachments: []*SlackAttachment{{ Color: slack.Color, - Text: attachmentText, + Text: attachmentText.String(), }}, } } diff --git a/internal/form/form.go b/internal/form/form.go index 12e4cee1d..5911dc9e9 100644 --- a/internal/form/form.go +++ b/internal/form/form.go @@ -62,7 +62,7 @@ func Assign(form any, data map[string]any) { } func getRuleBody(field reflect.StructField, prefix string) string { - for _, rule := range strings.Split(field.Tag.Get("binding"), ";") { + for rule := range strings.SplitSeq(field.Tag.Get("binding"), ";") { if strings.HasPrefix(rule, prefix) { return rule[len(prefix) : len(rule)-1] } diff --git a/internal/gitutil/tag.go b/internal/gitutil/tag.go index 16fd8bc08..d55d48e75 100644 --- a/internal/gitutil/tag.go +++ b/internal/gitutil/tag.go @@ -37,10 +37,7 @@ func (module) ListTagsAfter(repoPath, after string, limit int) (*TagsPage, error // No filter but has a limit, returns first X tags if after == "" && limit > 0 { - endIdx := limit - if limit > total { - endIdx = total - } + endIdx := min(limit, total) return &TagsPage{ Tags: all[:endIdx], HasLatest: true, diff --git a/internal/markup/markup.go b/internal/markup/markup.go index 26f8f8fcd..11d89af26 100644 --- a/internal/markup/markup.go +++ b/internal/markup/markup.go @@ -151,7 +151,7 @@ func RenderSpecialLink(rawBytes []byte, urlPrefix string, metas map[string]strin ms := MentionPattern.FindAll(rawBytes, -1) for _, m := range ms { m = m[bytes.Index(m, []byte("@")):] - rawBytes = bytes.ReplaceAll(rawBytes, m, []byte(fmt.Sprintf(`%s`, conf.Server.Subpath, m[1:], m))) + rawBytes = bytes.ReplaceAll(rawBytes, m, fmt.Appendf(nil, `%s`, conf.Server.Subpath, m[1:], m)) } rawBytes = RenderIssueIndexPattern(rawBytes, urlPrefix, metas) diff --git a/internal/route/admin/notice.go b/internal/route/admin/notice.go index 52eb06cad..d0cdc8e22 100644 --- a/internal/route/admin/notice.go +++ b/internal/route/admin/notice.go @@ -22,10 +22,7 @@ func Notices(c *context.Context) { c.Data["PageIsAdminNotices"] = true total := database.Handle.Notices().Count(c.Req.Context()) - page := c.QueryInt("page") - if page <= 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) c.Data["Page"] = paginater.New(int(total), conf.UI.Admin.NoticePagingNum, page, 5) notices, err := database.Handle.Notices().List(c.Req.Context(), page, conf.UI.Admin.NoticePagingNum) diff --git a/internal/route/api/v1/repo/commits.go b/internal/route/api/v1/repo/commits.go index f0c86ca53..5a580af90 100644 --- a/internal/route/api/v1/repo/commits.go +++ b/internal/route/api/v1/repo/commits.go @@ -82,11 +82,11 @@ func GetReferenceSHA(c *context.APIContext) { ref := c.Params("*") refType := 0 // 0-unknown, 1-branch, 2-tag - if strings.HasPrefix(ref, git.RefsHeads) { - ref = strings.TrimPrefix(ref, git.RefsHeads) + if after, ok := strings.CutPrefix(ref, git.RefsHeads); ok { + ref = after refType = 1 - } else if strings.HasPrefix(ref, git.RefsTags) { - ref = strings.TrimPrefix(ref, git.RefsTags) + } else if after, ok := strings.CutPrefix(ref, git.RefsTags); ok { + ref = after refType = 2 } else { if gitRepo.HasBranch(ref) { diff --git a/internal/route/home.go b/internal/route/home.go index 1a685d273..926d1ed5f 100644 --- a/internal/route/home.go +++ b/internal/route/home.go @@ -89,10 +89,7 @@ type UserSearchOptions struct { } func RenderUserSearch(c *context.Context, opts *UserSearchOptions) { - page := c.QueryInt("page") - if page <= 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) var ( users []*database.User diff --git a/internal/route/repo/commit.go b/internal/route/repo/commit.go index 0fa281bb5..18652b57d 100644 --- a/internal/route/repo/commit.go +++ b/internal/route/repo/commit.go @@ -41,10 +41,7 @@ func renderCommits(c *context.Context, filename string) { c.Data["PageIsCommits"] = true c.Data["FileName"] = filename - page := c.QueryInt("page") - if page < 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) pageSize := c.QueryInt("pageSize") if pageSize < 1 { pageSize = conf.UI.User.CommitsPagingNum diff --git a/internal/route/repo/editor.go b/internal/route/repo/editor.go index 9e3bb563a..ceccb3025 100644 --- a/internal/route/repo/editor.go +++ b/internal/route/repo/editor.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "path" + "slices" "strings" "github.com/cockroachdb/errors" @@ -230,11 +231,9 @@ func editFilePost(c *context.Context, f form.EditRepoFile, isNewFile bool) { return } - for _, file := range files { - if file == f.TreePath { - c.RenderWithErr(c.Tr("repo.editor.file_changed_while_editing", c.Repo.RepoLink+"/compare/"+lastCommit+"..."+c.Repo.CommitID), http.StatusConflict, tmplEditorEdit, &f) - return - } + if slices.Contains(files, f.TreePath) { + c.RenderWithErr(c.Tr("repo.editor.file_changed_while_editing", c.Repo.RepoLink+"/compare/"+lastCommit+"..."+c.Repo.CommitID), http.StatusConflict, tmplEditorEdit, &f) + return } } } diff --git a/internal/route/repo/issue.go b/internal/route/repo/issue.go index b3949e06d..ed1b6c664 100644 --- a/internal/route/repo/issue.go +++ b/internal/route/repo/issue.go @@ -4,6 +4,7 @@ import ( "fmt" "net/http" "net/url" + "slices" "strings" "time" @@ -148,10 +149,7 @@ func issues(c *context.Context, isPullList bool) { IsPull: isPullList, }) - page := c.QueryInt("page") - if page <= 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) var total int if !isShowClosed { @@ -623,13 +621,7 @@ func viewIssue(c *context.Context, isPullList bool) { marked[comment.PosterID] = comment.ShowTag - isAdded := false - for j := range participants { - if comment.Poster == participants[j] { - isAdded = true - break - } - } + isAdded := slices.Contains(participants, comment.Poster) if !isAdded && !issue.IsPoster(comment.Poster.ID) { participants = append(participants, comment.Poster) } @@ -1019,7 +1011,7 @@ func InitializeLabels(c *context.Context, f form.InitializeLabels) { } labels := make([]*database.Label, len(list)) - for i := 0; i < len(list); i++ { + for i := range list { labels[i] = &database.Label{ RepoID: c.Repo.Repository.ID, Name: list[i][0], @@ -1093,10 +1085,7 @@ func Milestones(c *context.Context) { c.Data["OpenCount"] = openCount c.Data["ClosedCount"] = closedCount - page := c.QueryInt("page") - if page <= 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) var total int if !isShowClosed { diff --git a/internal/route/repo/setting.go b/internal/route/repo/setting.go index 0adfa3217..94abf80bb 100644 --- a/internal/route/repo/setting.go +++ b/internal/route/repo/setting.go @@ -4,6 +4,7 @@ import ( "fmt" "io" "net/http" + "slices" "strings" "time" @@ -580,12 +581,7 @@ func SettingsGitHooks(c *context.Context) { } func isValidHookName(name git.HookName) bool { - for _, h := range git.ServerSideHooks { - if h == name { - return true - } - } - return false + return slices.Contains(git.ServerSideHooks, name) } func SettingsGitHooksEdit(c *context.Context) { diff --git a/internal/route/user/home.go b/internal/route/user/home.go index bc3c321af..9ab11b050 100644 --- a/internal/route/user/home.go +++ b/internal/route/user/home.go @@ -216,10 +216,7 @@ func Issues(c *context.Context) { filterMode = database.FilterMode(viewType) } - page := c.QueryInt("page") - if page <= 1 { - page = 1 - } + page := max(c.QueryInt("page"), 1) repoID := c.QueryInt64("repo") isShowClosed := c.Query("state") == "closed" diff --git a/internal/strutil/strutil.go b/internal/strutil/strutil.go index 8f6abbf43..96075a367 100644 --- a/internal/strutil/strutil.go +++ b/internal/strutil/strutil.go @@ -29,7 +29,7 @@ func RandomChars(n int) (string, error) { buffer := make([]byte, n) max := big.NewInt(int64(len(alphanum))) - for i := 0; i < n; i++ { + for i := range n { index, err := randomInt(max) if err != nil { return "", err diff --git a/internal/strutil/strutil_test.go b/internal/strutil/strutil_test.go index 081813b82..5a6072b15 100644 --- a/internal/strutil/strutil_test.go +++ b/internal/strutil/strutil_test.go @@ -40,7 +40,7 @@ func TestToUpperFirst(t *testing.T) { func TestRandomChars(t *testing.T) { cache := make(map[string]bool) - for i := 0; i < 100; i++ { + for range 100 { chars, err := RandomChars(10) if err != nil { t.Fatal(err) diff --git a/internal/testutil/exec.go b/internal/testutil/exec.go index 1dc3344b5..367100e7c 100644 --- a/internal/testutil/exec.go +++ b/internal/testutil/exec.go @@ -28,9 +28,9 @@ func Exec(helper string, envs ...string) (string, error) { // it is passed first. if strings.Contains(str, "no tests to run") { return "", errors.New("no tests to run") - } else if i := strings.Index(str, "PASS"); i >= 0 { + } else if before, _, ok := strings.Cut(str, "PASS"); ok { // Collect helper result - return strings.TrimSpace(str[:i]), nil + return strings.TrimSpace(before), nil } if err != nil {