diff --git a/models/issues/pull.go b/models/issues/pull.go index 0781fd0a2d..188ef00814 100644 --- a/models/issues/pull.go +++ b/models/issues/pull.go @@ -5,6 +5,7 @@ package issues import ( + "bufio" "context" "errors" "fmt" @@ -923,31 +924,30 @@ func MergeBlockedByOutdatedBranch(protectBranch *git_model.ProtectedBranch, pr * return protectBranch.BlockOnOutdatedBranch && pr.CommitsBehind > 0 } -// GetCodeOwnersFromContent returns the code owners configuration -// Return empty slice if files missing +// GetCodeOwnersFromReader returns the code owners configuration // Return warning messages on parsing errors // We're trying to do the best we can when parsing a file. // Invalid lines are skipped. Non-existent users and teams too. -func GetCodeOwnersFromContent(ctx context.Context, data string) ([]*CodeOwnerRule, []string) { - if len(data) == 0 { - return nil, nil - } +func GetCodeOwnersFromReader(ctx context.Context, rc io.ReadCloser, truncated bool) ([]*CodeOwnerRule, []string) { + defer rc.Close() + scanner := bufio.NewScanner(rc) - rules := make([]*CodeOwnerRule, 0) - lines := strings.Split(data, "\n") - warnings := make([]string, 0) + var rules []*CodeOwnerRule + var warnings []string + line := 0 + for scanner.Scan() { + line++ - for i, line := range lines { - tokens := TokenizeCodeOwnersLine(line) + tokens := TokenizeCodeOwnersLine(scanner.Text()) if len(tokens) == 0 { continue } else if len(tokens) < 2 { - warnings = append(warnings, fmt.Sprintf("Line: %d: incorrect format", i+1)) + warnings = append(warnings, fmt.Sprintf("Line: %d: incorrect format", line)) continue } rule, wr := ParseCodeOwnersLine(ctx, tokens) for _, w := range wr { - warnings = append(warnings, fmt.Sprintf("Line: %d: %s", i+1, w)) + warnings = append(warnings, fmt.Sprintf("Line: %d: %s", line, w)) } if rule == nil { continue @@ -955,6 +955,12 @@ func GetCodeOwnersFromContent(ctx context.Context, data string) ([]*CodeOwnerRul rules = append(rules, rule) } + if err := scanner.Err(); err != nil { + warnings = append(warnings, err.Error()) + } + if truncated { + warnings = append(warnings, fmt.Sprintf("File too big: truncated while on line %d", line)) + } return rules, warnings } diff --git a/routers/web/repo/view.go b/routers/web/repo/view.go index c7cc715fc1..d958a11f55 100644 --- a/routers/web/repo/view.go +++ b/routers/web/repo/view.go @@ -439,8 +439,8 @@ func renderFile(ctx *context.Context, entry *git.TreeEntry) { ctx.Data["FileError"] = ctx.Locale.Tr("actions.runs.invalid_workflow_helper", workFlowErr.Error()) } } else if slices.Contains([]string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"}, ctx.Repo.TreePath) { - if data, err := blob.GetBlobContent(setting.UI.MaxDisplayFileSize); err == nil { - _, warnings := issue_model.GetCodeOwnersFromContent(ctx, data) + if rc, size, err := blob.NewTruncatedReader(setting.UI.MaxDisplayFileSize); err == nil { + _, warnings := issue_model.GetCodeOwnersFromReader(ctx, rc, size > setting.UI.MaxDisplayFileSize) if len(warnings) > 0 { ctx.Data["FileWarning"] = strings.Join(warnings, "\n") } diff --git a/services/issue/pull.go b/services/issue/pull.go index b0a0c47d88..2eef1fbfa8 100644 --- a/services/issue/pull.go +++ b/services/issue/pull.go @@ -43,8 +43,6 @@ type ReviewRequestNotifier struct { } func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, pr *issues_model.PullRequest) ([]*ReviewRequestNotifier, error) { - files := []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"} - if pr.IsWorkInProgress(ctx) { return nil, nil } @@ -72,18 +70,17 @@ func PullRequestCodeOwnersReview(ctx context.Context, issue *issues_model.Issue, return nil, err } - var data string - for _, file := range files { + var rules []*issues_model.CodeOwnerRule + for _, file := range []string{"CODEOWNERS", "docs/CODEOWNERS", ".gitea/CODEOWNERS"} { if blob, err := commit.GetBlobByPath(file); err == nil { - data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize) + rc, size, err := blob.NewTruncatedReader(setting.UI.MaxDisplayFileSize) if err == nil { + rules, _ = issues_model.GetCodeOwnersFromReader(ctx, rc, size > setting.UI.MaxDisplayFileSize) break } } } - rules, _ := issues_model.GetCodeOwnersFromContent(ctx, data) - // get the mergebase mergeBase, err := getMergeBase(repo, pr, git.BranchPrefix+pr.BaseBranch, pr.GetGitRefName()) if err != nil {