summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authortechknowlogick <techknowlogick@gitea.io>2020-09-05 16:12:14 -0400
committerGitHub <noreply@github.com>2020-09-05 16:12:14 -0400
commit9a17e2830b6d0501c36e600595e68cd2d8cd90f3 (patch)
treeea05e1e50928062dfbaa7d7332f8a975a236c078 /modules
parent913ac9cacda864b6f0bcb6225c499bdbd8e9f90d (diff)
downloadgitea-9a17e2830b6d0501c36e600595e68cd2d8cd90f3.tar.gz
gitea-9a17e2830b6d0501c36e600595e68cd2d8cd90f3.zip
refactor repo_stats to use os.pipe (#11726)
* refactor repo_stats to use os.pipe * woops. missing reader. * stdout not stderr, woops * Fix copyright date and ensure that the stderr is collected Signed-off-by: Andrew Thornton <art27@cantab.net> Co-authored-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'modules')
-rw-r--r--modules/git/command.go2
-rw-r--r--modules/git/repo_stats.go151
2 files changed, 86 insertions, 67 deletions
diff --git a/modules/git/command.go b/modules/git/command.go
index e0170b1723..d40c0bfa23 100644
--- a/modules/git/command.go
+++ b/modules/git/command.go
@@ -1,5 +1,5 @@
-// Copyright 2020 The Gitea Authors. All rights reserved.
// Copyright 2015 The Gogs Authors. All rights reserved.
+// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
diff --git a/modules/git/repo_stats.go b/modules/git/repo_stats.go
index bfa368b6df..59b8177401 100644
--- a/modules/git/repo_stats.go
+++ b/modules/git/repo_stats.go
@@ -6,8 +6,9 @@ package git
import (
"bufio"
- "bytes"
+ "context"
"fmt"
+ "os"
"sort"
"strconv"
"strings"
@@ -49,6 +50,15 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
}
stats.CommitCountInAllBranches = c
+ stdoutReader, stdoutWriter, err := os.Pipe()
+ if err != nil {
+ return nil, err
+ }
+ defer func() {
+ _ = stdoutReader.Close()
+ _ = stdoutWriter.Close()
+ }()
+
args := []string{"log", "--numstat", "--no-merges", "--pretty=format:---%n%h%n%an%n%ae%n", "--date=iso", fmt.Sprintf("--since='%s'", since)}
if len(branch) == 0 {
args = append(args, "--branches=*")
@@ -56,79 +66,88 @@ func (repo *Repository) GetCodeActivityStats(fromTime time.Time, branch string)
args = append(args, "--first-parent", branch)
}
- stdout, err = NewCommand(args...).RunInDirBytes(repo.Path)
- if err != nil {
- return nil, err
- }
+ stderr := new(strings.Builder)
+ err = NewCommand(args...).RunInDirTimeoutEnvFullPipelineFunc(
+ nil, -1, repo.Path,
+ stdoutWriter, stderr, nil,
+ func(ctx context.Context, cancel context.CancelFunc) error {
+ _ = stdoutWriter.Close()
- scanner := bufio.NewScanner(bytes.NewReader(stdout))
- scanner.Split(bufio.ScanLines)
- stats.CommitCount = 0
- stats.Additions = 0
- stats.Deletions = 0
- authors := make(map[string]*CodeActivityAuthor)
- files := make(map[string]bool)
- var author string
- p := 0
- for scanner.Scan() {
- l := strings.TrimSpace(scanner.Text())
- if l == "---" {
- p = 1
- } else if p == 0 {
- continue
- } else {
- p++
- }
- if p > 4 && len(l) == 0 {
- continue
- }
- switch p {
- case 1: // Separator
- case 2: // Commit sha-1
- stats.CommitCount++
- case 3: // Author
- author = l
- case 4: // E-mail
- email := strings.ToLower(l)
- if _, ok := authors[email]; !ok {
- authors[email] = &CodeActivityAuthor{
- Name: author,
- Email: email,
- Commits: 0,
+ scanner := bufio.NewScanner(stdoutReader)
+ scanner.Split(bufio.ScanLines)
+ stats.CommitCount = 0
+ stats.Additions = 0
+ stats.Deletions = 0
+ authors := make(map[string]*CodeActivityAuthor)
+ files := make(map[string]bool)
+ var author string
+ p := 0
+ for scanner.Scan() {
+ l := strings.TrimSpace(scanner.Text())
+ if l == "---" {
+ p = 1
+ } else if p == 0 {
+ continue
+ } else {
+ p++
}
- }
- authors[email].Commits++
- default: // Changed file
- if parts := strings.Fields(l); len(parts) >= 3 {
- if parts[0] != "-" {
- if c, err := strconv.ParseInt(strings.TrimSpace(parts[0]), 10, 64); err == nil {
- stats.Additions += c
- }
+ if p > 4 && len(l) == 0 {
+ continue
}
- if parts[1] != "-" {
- if c, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err == nil {
- stats.Deletions += c
+ switch p {
+ case 1: // Separator
+ case 2: // Commit sha-1
+ stats.CommitCount++
+ case 3: // Author
+ author = l
+ case 4: // E-mail
+ email := strings.ToLower(l)
+ if _, ok := authors[email]; !ok {
+ authors[email] = &CodeActivityAuthor{
+ Name: author,
+ Email: email,
+ Commits: 0,
+ }
+ }
+ authors[email].Commits++
+ default: // Changed file
+ if parts := strings.Fields(l); len(parts) >= 3 {
+ if parts[0] != "-" {
+ if c, err := strconv.ParseInt(strings.TrimSpace(parts[0]), 10, 64); err == nil {
+ stats.Additions += c
+ }
+ }
+ if parts[1] != "-" {
+ if c, err := strconv.ParseInt(strings.TrimSpace(parts[1]), 10, 64); err == nil {
+ stats.Deletions += c
+ }
+ }
+ if _, ok := files[parts[2]]; !ok {
+ files[parts[2]] = true
+ }
}
- }
- if _, ok := files[parts[2]]; !ok {
- files[parts[2]] = true
}
}
- }
- }
- a := make([]*CodeActivityAuthor, 0, len(authors))
- for _, v := range authors {
- a = append(a, v)
+ a := make([]*CodeActivityAuthor, 0, len(authors))
+ for _, v := range authors {
+ a = append(a, v)
+ }
+ // Sort authors descending depending on commit count
+ sort.Slice(a, func(i, j int) bool {
+ return a[i].Commits > a[j].Commits
+ })
+
+ stats.AuthorCount = int64(len(authors))
+ stats.ChangedFiles = int64(len(files))
+ stats.Authors = a
+
+ _ = stdoutReader.Close()
+ return nil
+ })
+ if err != nil {
+ return nil, fmt.Errorf("Failed to get GetCodeActivityStats for repository.\nError: %w\nStderr: %s", err, stderr)
}
- // Sort authors descending depending on commit count
- sort.Slice(a, func(i, j int) bool {
- return a[i].Commits > a[j].Commits
- })
-
- stats.AuthorCount = int64(len(authors))
- stats.ChangedFiles = int64(len(files))
- stats.Authors = a
return stats, nil
}