diff --git a/internal/lefthook/add.go b/internal/lefthook/add.go index d77e8464..0fcc9cf2 100644 --- a/internal/lefthook/add.go +++ b/internal/lefthook/add.go @@ -5,6 +5,7 @@ import ( "path/filepath" "github.com/evilmartians/lefthook/internal/config" + "github.com/evilmartians/lefthook/internal/templates" ) const defaultDirMode = 0o755 @@ -39,7 +40,7 @@ func (l *Lefthook) Add(args *AddArgs) error { return err } - err = l.addHook(args.Hook, "", false) + err = l.addHook(args.Hook, templates.Args{}) if err != nil { return err } diff --git a/internal/lefthook/install.go b/internal/lefthook/install.go index 1724a97e..549f207d 100644 --- a/internal/lefthook/install.go +++ b/internal/lefthook/install.go @@ -131,6 +131,22 @@ func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, checkHashSum, force b return err } + rootsMap := make(map[string]struct{}) + for _, hook := range cfg.Hooks { + for _, command := range hook.Commands { + if len(command.Root) > 0 { + root := strings.Trim(command.Root, "/") + if _, ok := rootsMap[root]; !ok { + rootsMap[root] = struct{}{} + } + } + } + } + roots := make([]string, 0, len(rootsMap)) + for root := range rootsMap { + roots = append(roots, root) + } + hookNames := make([]string, 0, len(cfg.Hooks)+1) for hook := range cfg.Hooks { hookNames = append(hookNames, hook) @@ -139,12 +155,22 @@ func (l *Lefthook) createHooksIfNeeded(cfg *config.Config, checkHashSum, force b return err } - if err = l.addHook(hook, cfg.Rc, cfg.AssertLefthookInstalled); err != nil { + templateArgs := templates.Args{ + Rc: cfg.Rc, + AssertLefthookInstalled: cfg.AssertLefthookInstalled, + Roots: roots, + } + if err = l.addHook(hook, templateArgs); err != nil { return err } } - if err = l.addHook(config.GhostHookName, cfg.Rc, cfg.AssertLefthookInstalled); err != nil { + templateArgs := templates.Args{ + Rc: cfg.Rc, + AssertLefthookInstalled: cfg.AssertLefthookInstalled, + Roots: roots, + } + if err = l.addHook(config.GhostHookName, templateArgs); err != nil { return nil } diff --git a/internal/lefthook/lefthook.go b/internal/lefthook/lefthook.go index 29de2f51..ae1e1563 100644 --- a/internal/lefthook/lefthook.go +++ b/internal/lefthook/lefthook.go @@ -117,9 +117,9 @@ func (l *Lefthook) cleanHook(hook string, force bool) error { } // Creates a hook file using hook template. -func (l *Lefthook) addHook(hook, rc string, assertLefthookInstalled bool) error { +func (l *Lefthook) addHook(hook string, args templates.Args) error { hookPath := filepath.Join(l.repo.HooksPath, hook) return afero.WriteFile( - l.Fs, hookPath, templates.Hook(hook, rc, assertLefthookInstalled), hookFileMode, + l.Fs, hookPath, templates.Hook(hook, args), hookFileMode, ) } diff --git a/internal/templates/hook.tmpl b/internal/templates/hook.tmpl index d0c370ae..2698b41a 100644 --- a/internal/templates/hook.tmpl +++ b/internal/templates/hook.tmpl @@ -33,6 +33,18 @@ call_lefthook() elif test -f "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}}" then "$dir/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{.Extension}}" "$@" + {{ $extension := .Extension }} + {{- range .Roots -}} + elif test -f "$dir/{{.}}/node_modules/lefthook/bin/index.js" + then + "$dir/{{.}}/node_modules/lefthook/bin/index.js" "$@" + elif test -f "$dir/{{.}}/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{$extension}}" + then + "$dir/{{.}}/node_modules/@evilmartians/lefthook/bin/lefthook_${osArch}_${cpuArch}/lefthook{{$extension}}" "$@" + elif test -f "$dir/{{.}}/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{$extension}}" + then + "$dir/{{.}}/node_modules/@evilmartians/lefthook-installer/bin/lefthook_${osArch}_${cpuArch}/lefthook{{$extension}}" "$@" + {{end}} elif bundle exec lefthook -h >/dev/null 2>&1 then bundle exec lefthook "$@" diff --git a/internal/templates/templates.go b/internal/templates/templates.go index 8b1da93e..3692795c 100644 --- a/internal/templates/templates.go +++ b/internal/templates/templates.go @@ -13,21 +13,29 @@ const checksumFormat = "%s %d\n" //go:embed * var templatesFS embed.FS +type Args struct { + Rc string + AssertLefthookInstalled bool + Roots []string +} + type hookTmplData struct { HookName string Extension string Rc string + Roots []string AssertLefthookInstalled bool } -func Hook(hookName, rc string, assertLefthookInstalled bool) []byte { +func Hook(hookName string, args Args) []byte { buf := &bytes.Buffer{} t := template.Must(template.ParseFS(templatesFS, "hook.tmpl")) err := t.Execute(buf, hookTmplData{ HookName: hookName, Extension: getExtension(), - Rc: rc, - AssertLefthookInstalled: assertLefthookInstalled, + Rc: args.Rc, + AssertLefthookInstalled: args.AssertLefthookInstalled, + Roots: args.Roots, }) if err != nil { panic(err)