Fast implementation of Git in pure Go
at master 89 lines 2.3 kB view raw
1package receivepack 2 3import ( 4 "context" 5 "io" 6 7 "codeberg.org/lindenii/furgit/objectid" 8 "codeberg.org/lindenii/furgit/objectstore" 9 "codeberg.org/lindenii/furgit/receivepack/service" 10 "codeberg.org/lindenii/furgit/refstore" 11) 12 13type HookIO struct { 14 Progress io.Writer 15 Error io.Writer 16} 17 18// RefUpdate is one requested reference update presented to a receive-pack hook. 19type RefUpdate struct { 20 Name string 21 OldID objectid.ObjectID 22 NewID objectid.ObjectID 23} 24 25// UpdateDecision is one hook decision for a requested reference update. 26type UpdateDecision struct { 27 Accept bool 28 Message string 29} 30 31// HookRequest is the input presented to a receive-pack hook before quarantine 32// promotion and ref updates. 33type HookRequest struct { 34 Refs refstore.ReadingStore 35 ExistingObjects objectstore.Store 36 QuarantinedObjects objectstore.Store 37 Updates []RefUpdate 38 PushOptions []string 39 IO HookIO 40} 41 42// Hook decides whether each requested update should proceed. 43// 44// The hook runs after pack ingestion into quarantine and before quarantine 45// promotion or ref updates. The returned decisions must have the same length as 46// HookRequest.Updates. 47type Hook func(context.Context, HookRequest) ([]UpdateDecision, error) 48 49func translateHook(hook Hook) service.Hook { 50 if hook == nil { 51 return nil 52 } 53 54 return func(ctx context.Context, req service.HookRequest) ([]service.UpdateDecision, error) { 55 translatedUpdates := make([]RefUpdate, 0, len(req.Updates)) 56 for _, update := range req.Updates { 57 translatedUpdates = append(translatedUpdates, RefUpdate{ 58 Name: update.Name, 59 OldID: update.OldID, 60 NewID: update.NewID, 61 }) 62 } 63 64 decisions, err := hook(ctx, HookRequest{ 65 Refs: req.Refs, 66 ExistingObjects: req.ExistingObjects, 67 QuarantinedObjects: req.QuarantinedObjects, 68 Updates: translatedUpdates, 69 PushOptions: append([]string(nil), req.PushOptions...), 70 IO: HookIO{ 71 Progress: req.IO.Progress, 72 Error: req.IO.Error, 73 }, 74 }) 75 if err != nil { 76 return nil, err 77 } 78 79 out := make([]service.UpdateDecision, 0, len(decisions)) 80 for _, decision := range decisions { 81 out = append(out, service.UpdateDecision{ 82 Accept: decision.Accept, 83 Message: decision.Message, 84 }) 85 } 86 87 return out, nil 88 } 89}