aboutsummaryrefslogtreecommitdiff
path: root/receivepack/service/run_hook.go
blob: 90ab2e78073e1127ad9e1a5ab181b8c8b203f2a3 (about) (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package service

import (
	"context"

	"codeberg.org/lindenii/furgit/internal/utils"
)

func (service *Service) runHook(
	ctx context.Context,
	req *Request,
	commands []Command,
	quarantineName string,
) (
	allowedCommands []Command,
	allowedIndices []int,
	rejected map[int]string,
	ok bool,
	errText string,
) {
	allowedCommands = append([]Command(nil), commands...)

	allowedIndices = make([]int, 0, len(commands))
	for index := range commands {
		allowedIndices = append(allowedIndices, index)
	}

	rejected = make(map[int]string)
	if service.opts.Hook == nil {
		return allowedCommands, allowedIndices, rejected, true, ""
	}

	utils.FprintfBestEffort(service.opts.Progress, "running hooks...\r")

	quarantinedObjects, err := service.openQuarantinedObjects(quarantineName)
	if err != nil {
		utils.FprintfBestEffort(service.opts.Progress, "running hooks: failed: %v.\n", err)

		return nil, nil, nil, false, err.Error()
	}

	defer func() {
		_ = quarantinedObjects.Close()
	}()

	decisions, err := service.opts.Hook(ctx, HookRequest{
		Refs:               service.opts.Refs,
		ExistingObjects:    service.opts.ExistingObjects,
		QuarantinedObjects: quarantinedObjects,
		Updates:            buildHookUpdates(commands),
		PushOptions:        append([]string(nil), req.PushOptions...),
		IO:                 service.opts.HookIO,
	})
	if err != nil {
		utils.FprintfBestEffort(service.opts.Progress, "running hooks: failed: %v.\n", err)

		return nil, nil, nil, false, err.Error()
	}

	if len(decisions) != len(commands) {
		utils.FprintfBestEffort(service.opts.Progress, "running hooks: failed: wrong decision count.\n")

		return nil, nil, nil, false, "hook returned wrong number of update decisions"
	}

	allowedCommands = allowedCommands[:0]
	allowedIndices = allowedIndices[:0]

	for index, decision := range decisions {
		if decision.Accept {
			allowedCommands = append(allowedCommands, commands[index])
			allowedIndices = append(allowedIndices, index)

			continue
		}

		message := decision.Message
		if message == "" {
			message = "rejected by hook"
		}

		rejected[index] = message
	}

	utils.FprintfBestEffort(
		service.opts.Progress,
		"running hooks: done (%d/%d accepted).\n",
		len(allowedCommands),
		len(commands),
	)

	return allowedCommands, allowedIndices, rejected, true, ""
}