aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/hook.go
diff options
context:
space:
mode:
Diffstat (limited to 'cmd/hook.go')
-rw-r--r--cmd/hook.go217
1 files changed, 174 insertions, 43 deletions
diff --git a/cmd/hook.go b/cmd/hook.go
index 7e45304841..03fa15aabc 100644
--- a/cmd/hook.go
+++ b/cmd/hook.go
@@ -21,6 +21,10 @@ import (
"github.com/urfave/cli"
)
+const (
+ hookBatchSize = 30
+)
+
var (
// CmdHook represents the available hooks sub-command.
CmdHook = cli.Command{
@@ -75,12 +79,25 @@ Gitea or set your environment appropriately.`, "")
prID, _ := strconv.ParseInt(os.Getenv(models.ProtectedBranchPRID), 10, 64)
isDeployKey, _ := strconv.ParseBool(os.Getenv(models.EnvIsDeployKey))
- buf := bytes.NewBuffer(nil)
+ hookOptions := private.HookOptions{
+ UserID: userID,
+ GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
+ GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
+ GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
+ ProtectedBranchID: prID,
+ IsDeployKey: isDeployKey,
+ }
+
scanner := bufio.NewScanner(os.Stdin)
- for scanner.Scan() {
- buf.Write(scanner.Bytes())
- buf.WriteByte('\n')
+ oldCommitIDs := make([]string, hookBatchSize)
+ newCommitIDs := make([]string, hookBatchSize)
+ refFullNames := make([]string, hookBatchSize)
+ count := 0
+ total := 0
+ lastline := 0
+
+ for scanner.Scan() {
// TODO: support news feeds for wiki
if isWiki {
continue
@@ -94,29 +111,72 @@ Gitea or set your environment appropriately.`, "")
oldCommitID := string(fields[0])
newCommitID := string(fields[1])
refFullName := string(fields[2])
+ total++
+ lastline++
// If the ref is a branch, check if it's protected
if strings.HasPrefix(refFullName, git.BranchPrefix) {
- statusCode, msg := private.HookPreReceive(username, reponame, private.HookOptions{
- OldCommitID: oldCommitID,
- NewCommitID: newCommitID,
- RefFullName: refFullName,
- UserID: userID,
- GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
- GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
- GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
- ProtectedBranchID: prID,
- IsDeployKey: isDeployKey,
- })
- switch statusCode {
- case http.StatusInternalServerError:
- fail("Internal Server Error", msg)
- case http.StatusForbidden:
- fail(msg, "")
+ oldCommitIDs[count] = oldCommitID
+ newCommitIDs[count] = newCommitID
+ refFullNames[count] = refFullName
+ count++
+ fmt.Fprintf(os.Stdout, "*")
+ os.Stdout.Sync()
+
+ if count >= hookBatchSize {
+ fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
+ os.Stdout.Sync()
+
+ hookOptions.OldCommitIDs = oldCommitIDs
+ hookOptions.NewCommitIDs = newCommitIDs
+ hookOptions.RefFullNames = refFullNames
+ statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
+ switch statusCode {
+ case http.StatusOK:
+ // no-op
+ case http.StatusInternalServerError:
+ fail("Internal Server Error", msg)
+ default:
+ fail(msg, "")
+ }
+ count = 0
+ lastline = 0
}
+ } else {
+ fmt.Fprintf(os.Stdout, ".")
+ os.Stdout.Sync()
+ }
+ if lastline >= hookBatchSize {
+ fmt.Fprintf(os.Stdout, "\n")
+ os.Stdout.Sync()
+ lastline = 0
}
}
+ if count > 0 {
+ hookOptions.OldCommitIDs = oldCommitIDs[:count]
+ hookOptions.NewCommitIDs = newCommitIDs[:count]
+ hookOptions.RefFullNames = refFullNames[:count]
+
+ fmt.Fprintf(os.Stdout, " Checking %d branches\n", count)
+ os.Stdout.Sync()
+
+ statusCode, msg := private.HookPreReceive(username, reponame, hookOptions)
+ switch statusCode {
+ case http.StatusInternalServerError:
+ fail("Internal Server Error", msg)
+ case http.StatusForbidden:
+ fail(msg, "")
+ }
+ } else if lastline > 0 {
+ fmt.Fprintf(os.Stdout, "\n")
+ os.Stdout.Sync()
+ lastline = 0
+ }
+
+ fmt.Fprintf(os.Stdout, "Checked %d references in total\n", total)
+ os.Stdout.Sync()
+
return nil
}
@@ -156,12 +216,24 @@ Gitea or set your environment appropriately.`, "")
pusherID, _ := strconv.ParseInt(os.Getenv(models.EnvPusherID), 10, 64)
pusherName := os.Getenv(models.EnvPusherName)
- buf := bytes.NewBuffer(nil)
+ hookOptions := private.HookOptions{
+ UserName: pusherName,
+ UserID: pusherID,
+ GitAlternativeObjectDirectories: os.Getenv(private.GitAlternativeObjectDirectories),
+ GitObjectDirectory: os.Getenv(private.GitObjectDirectory),
+ GitQuarantinePath: os.Getenv(private.GitQuarantinePath),
+ }
+ oldCommitIDs := make([]string, hookBatchSize)
+ newCommitIDs := make([]string, hookBatchSize)
+ refFullNames := make([]string, hookBatchSize)
+ count := 0
+ total := 0
+ wasEmpty := false
+ masterPushed := false
+ results := make([]private.HookPostReceiveBranchResult, 0)
+
scanner := bufio.NewScanner(os.Stdin)
for scanner.Scan() {
- buf.Write(scanner.Bytes())
- buf.WriteByte('\n')
-
// TODO: support news feeds for wiki
if isWiki {
continue
@@ -172,36 +244,95 @@ Gitea or set your environment appropriately.`, "")
continue
}
- oldCommitID := string(fields[0])
- newCommitID := string(fields[1])
- refFullName := string(fields[2])
+ fmt.Fprintf(os.Stdout, ".")
+ oldCommitIDs[count] = string(fields[0])
+ newCommitIDs[count] = string(fields[1])
+ refFullNames[count] = string(fields[2])
+ if refFullNames[count] == git.BranchPrefix+"master" && newCommitIDs[count] != git.EmptySHA && count == total {
+ masterPushed = true
+ }
+ count++
+ total++
+ os.Stdout.Sync()
+
+ if count >= hookBatchSize {
+ fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
+ os.Stdout.Sync()
+ hookOptions.OldCommitIDs = oldCommitIDs
+ hookOptions.NewCommitIDs = newCommitIDs
+ hookOptions.RefFullNames = refFullNames
+ resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
+ if resp == nil {
+ hookPrintResults(results)
+ fail("Internal Server Error", err)
+ }
+ wasEmpty = wasEmpty || resp.RepoWasEmpty
+ results = append(results, resp.Results...)
+ count = 0
+ }
+ }
+
+ if count == 0 {
+ if wasEmpty && masterPushed {
+ // We need to tell the repo to reset the default branch to master
+ err := private.SetDefaultBranch(repoUser, repoName, "master")
+ if err != nil {
+ fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
+ }
+ }
+ fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
+ os.Stdout.Sync()
+
+ hookPrintResults(results)
+ return nil
+ }
- res, err := private.HookPostReceive(repoUser, repoName, private.HookOptions{
- OldCommitID: oldCommitID,
- NewCommitID: newCommitID,
- RefFullName: refFullName,
- UserID: pusherID,
- UserName: pusherName,
- })
+ hookOptions.OldCommitIDs = oldCommitIDs[:count]
+ hookOptions.NewCommitIDs = newCommitIDs[:count]
+ hookOptions.RefFullNames = refFullNames[:count]
- if res == nil {
- fail("Internal Server Error", err)
+ fmt.Fprintf(os.Stdout, " Processing %d references\n", count)
+ os.Stdout.Sync()
+
+ resp, err := private.HookPostReceive(repoUser, repoName, hookOptions)
+ if resp == nil {
+ hookPrintResults(results)
+ fail("Internal Server Error", err)
+ }
+ wasEmpty = wasEmpty || resp.RepoWasEmpty
+ results = append(results, resp.Results...)
+
+ fmt.Fprintf(os.Stdout, "Processed %d references in total\n", total)
+ os.Stdout.Sync()
+
+ if wasEmpty && masterPushed {
+ // We need to tell the repo to reset the default branch to master
+ err := private.SetDefaultBranch(repoUser, repoName, "master")
+ if err != nil {
+ fail("Internal Server Error", "SetDefaultBranch failed with Error: %v", err)
}
+ }
+
+ hookPrintResults(results)
- if res["message"] == false {
+ return nil
+}
+
+func hookPrintResults(results []private.HookPostReceiveBranchResult) {
+ for _, res := range results {
+ if !res.Message {
continue
}
fmt.Fprintln(os.Stderr, "")
- if res["create"] == true {
- fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res["branch"])
- fmt.Fprintf(os.Stderr, " %s\n", res["url"])
+ if res.Create {
+ fmt.Fprintf(os.Stderr, "Create a new pull request for '%s':\n", res.Branch)
+ fmt.Fprintf(os.Stderr, " %s\n", res.URL)
} else {
fmt.Fprint(os.Stderr, "Visit the existing pull request:\n")
- fmt.Fprintf(os.Stderr, " %s\n", res["url"])
+ fmt.Fprintf(os.Stderr, " %s\n", res.URL)
}
fmt.Fprintln(os.Stderr, "")
+ os.Stderr.Sync()
}
-
- return nil
}