|
| 1 | +// This Source Code Form is subject to the terms of the Mozilla Public |
| 2 | +// License, v. 2.0. If a copy of the MPL was not distributed with this |
| 3 | +// file, You can obtain one at http://mozilla.org/MPL/2.0/. |
| 4 | + |
| 5 | +package lefthook |
| 6 | + |
| 7 | +// Pre-commit stage keys: stable names for Hook.Group so multiple project blocks |
| 8 | +// can append jobs to the same ordered group. Each value is both the lookup key |
| 9 | +// and the group's emitted `name:`. |
| 10 | +const ( |
| 11 | + // PreCommitFixStage is stage 1: mutating formatters/generators, re-staged via stage_fixed. |
| 12 | + PreCommitFixStage = "fix" |
| 13 | + // PreCommitLintStage is stage 2: verification, runs after the fix stage. |
| 14 | + PreCommitLintStage = "lint" |
| 15 | + |
| 16 | + // HookGroupPreCommit is the lefthook "pre-commit" hook name. |
| 17 | + HookGroupPreCommit = "pre-commit" |
| 18 | + // HookGroupCommitMsg is the lefthook "commit-msg" hook name. |
| 19 | + HookGroupCommitMsg = "commit-msg" |
| 20 | +) |
| 21 | + |
| 22 | +// Hook represents the configuration for a single git hook (e.g. pre-commit) |
| 23 | +// inside lefthook.yml. A hook can declare either Commands (a named map) or |
| 24 | +// Jobs (an ordered list with nested groups) — see lefthook docs for the |
| 25 | +// trade-off; mixing both in a single hook is generally not recommended. |
| 26 | +type Hook struct { //nolint:govet |
| 27 | + // Parallel is a pointer so an explicit `parallel: false` can be emitted |
| 28 | + // (with a plain bool + omitempty the false zero-value would be suppressed). |
| 29 | + // Only meaningful for Commands-style hooks; Jobs-style hooks control |
| 30 | + // parallelism per-Group. |
| 31 | + Parallel *bool `yaml:"parallel,omitempty"` |
| 32 | + Piped bool `yaml:"piped,omitempty"` |
| 33 | + Commands map[string]*Command `yaml:"commands,omitempty"` |
| 34 | + Jobs []*Job `yaml:"jobs,omitempty"` |
| 35 | +} |
| 36 | + |
| 37 | +// WithParallel sets the hook-level parallel flag (Commands-style hooks only). |
| 38 | +func (h *Hook) WithParallel(parallel bool) *Hook { |
| 39 | + h.Parallel = ¶llel |
| 40 | + |
| 41 | + return h |
| 42 | +} |
| 43 | + |
| 44 | +// WithPiped enables piped (sequential, fail-fast) execution of this hook's commands. |
| 45 | +func (h *Hook) WithPiped(piped bool) *Hook { |
| 46 | + h.Piped = piped |
| 47 | + |
| 48 | + return h |
| 49 | +} |
| 50 | + |
| 51 | +// Command returns the named command on this hook, creating it on first access. |
| 52 | +func (h *Hook) Command(name string) *Command { |
| 53 | + if c, ok := h.Commands[name]; ok { |
| 54 | + return c |
| 55 | + } |
| 56 | + |
| 57 | + if h.Commands == nil { |
| 58 | + h.Commands = map[string]*Command{} |
| 59 | + } |
| 60 | + |
| 61 | + c := &Command{} |
| 62 | + h.Commands[name] = c |
| 63 | + |
| 64 | + return c |
| 65 | +} |
| 66 | + |
| 67 | +// Job appends a new job to this hook's Jobs list and returns it for further |
| 68 | +// configuration. Each top-level entry runs in declaration order; use AsGroup |
| 69 | +// on the returned job to nest a parallel/sequential group of inner jobs. |
| 70 | +func (h *Hook) Job() *Job { |
| 71 | + j := &Job{} |
| 72 | + |
| 73 | + h.Jobs = append(h.Jobs, j) |
| 74 | + |
| 75 | + return j |
| 76 | +} |
| 77 | + |
| 78 | +// Group returns the named group on this hook, wrapped in a Job entry, creating |
| 79 | +// it on first access (mirroring makefile.Output.Target). The name is emitted as |
| 80 | +// the wrapping job's `name:` and doubles as the lookup key, so different project |
| 81 | +// blocks can contribute jobs to the same group regardless of compile order; |
| 82 | +// group emission order follows first-creation order. |
| 83 | +func (h *Hook) Group(name string) *Group { |
| 84 | + for _, j := range h.Jobs { |
| 85 | + if j.Group != nil && j.Name == name { |
| 86 | + return j.Group |
| 87 | + } |
| 88 | + } |
| 89 | + |
| 90 | + g := &Group{} |
| 91 | + |
| 92 | + h.Jobs = append(h.Jobs, &Job{Name: name, Group: g}) |
| 93 | + |
| 94 | + return g |
| 95 | +} |
0 commit comments