1package git23import (4 "os"5 "path/filepath"6)78// DefaultHooksDir is the default directory for Git hooks.9const DefaultHooksDir = "hooks"1011// NewHook creates and returns a new hook with given name. Update method must be12// called to actually save the hook to disk.13func (r *Repository) NewHook(dir string, name HookName) *Hook {14 return &Hook{15 name: name,16 path: filepath.Join(r.path, dir, string(name)),17 }18}1920// Hook returns a Git hook by given name in the repository. Giving empty21// directory will use the default directory. It returns an os.ErrNotExist if22// both active and sample hook do not exist.23func (r *Repository) Hook(dir string, name HookName) (*Hook, error) {24 if dir == "" {25 dir = DefaultHooksDir26 }27 // 1. Check if there is an active hook.28 fpath := filepath.Join(r.path, dir, string(name))29 if isFile(fpath) {30 p, err := os.ReadFile(fpath)31 if err != nil {32 return nil, err33 }34 return &Hook{35 name: name,36 path: fpath,37 content: string(p),38 }, nil39 }4041 // 2. Check if sample content exists.42 sample := ServerSideHookSamples[name]43 if sample != "" {44 return &Hook{45 name: name,46 path: fpath,47 isSample: true,48 content: sample,49 }, nil50 }5152 return nil, os.ErrNotExist53}5455// Hooks returns a list of Git hooks found in the repository. Giving empty56// directory will use the default directory. It may return an empty slice when57// no hooks found.58func (r *Repository) Hooks(dir string) ([]*Hook, error) {59 hooks := make([]*Hook, 0, len(ServerSideHooks))60 for _, name := range ServerSideHooks {61 h, err := r.Hook(dir, name)62 if err != nil {63 if err == os.ErrNotExist {64 continue65 }66 return nil, err67 }68 hooks = append(hooks, h)69 }70 return hooks, nil71}