ref: 3ce59c3248dec0eb0f918c42f37f53bc2ac20425
dir: /network/receivepack/hook.go/
package receivepack
import (
"context"
"codeberg.org/lindenii/furgit/common/iowrap"
commitgraphread "codeberg.org/lindenii/furgit/format/commitgraph/read"
"codeberg.org/lindenii/furgit/network/receivepack/service"
objectid "codeberg.org/lindenii/furgit/object/id"
objectstore "codeberg.org/lindenii/furgit/object/store"
refstore "codeberg.org/lindenii/furgit/ref/store"
)
type HookIO struct {
Progress iowrap.WriteFlusher
Error iowrap.WriteFlusher
}
// RefUpdate is one requested reference update presented to a receive-pack hook.
type RefUpdate struct {
Name string
OldID objectid.ObjectID
NewID objectid.ObjectID
}
// UpdateDecision is one hook decision for a requested reference update.
type UpdateDecision struct {
Accept bool
Message string
}
// HookRequest is the input presented to a receive-pack hook before quarantine
// promotion and ref updates.
//
// Labels: Life-Call.
type HookRequest struct {
Refs refstore.Reader
ExistingObjects objectstore.Reader
// QuarantinedObjects exposes quarantined objects for this push.
//
// When the push did not create a quarantine, QuarantinedObjects is nil.
QuarantinedObjects objectstore.Reader
CommitGraph *commitgraphread.Reader
Updates []RefUpdate
PushOptions []string
IO HookIO
}
// Hook decides whether each requested update should proceed.
//
// The hook runs after pack ingestion into quarantine and before quarantine
// promotion or ref updates. The returned decisions must have the same length as
// HookRequest.Updates.
type Hook func(context.Context, HookRequest) ([]UpdateDecision, error)
func translateHook(hook Hook) service.Hook {
if hook == nil {
return nil
}
return func(ctx context.Context, req service.HookRequest) ([]service.UpdateDecision, error) {
translatedUpdates := make([]RefUpdate, 0, len(req.Updates))
for _, update := range req.Updates {
translatedUpdates = append(translatedUpdates, RefUpdate{
Name: update.Name,
OldID: update.OldID,
NewID: update.NewID,
})
}
decisions, err := hook(ctx, HookRequest{
Refs: req.Refs,
ExistingObjects: req.ExistingObjects,
QuarantinedObjects: req.QuarantinedObjects,
CommitGraph: req.CommitGraph,
Updates: translatedUpdates,
PushOptions: append([]string(nil), req.PushOptions...),
IO: HookIO{
Progress: req.IO.Progress,
Error: req.IO.Error,
},
})
if err != nil {
return nil, err
}
out := make([]service.UpdateDecision, 0, len(decisions))
for _, decision := range decisions {
out = append(out, service.UpdateDecision{
Accept: decision.Accept,
Message: decision.Message,
})
}
return out, nil
}
}