Skip to content

Commit

Permalink
feature: Allow suppressing execution output (#309)
Browse files Browse the repository at this point in the history
* feature: Allow supresssing execution output

Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>

* chore: Refactor and rename type to SkipSettings

Signed-off-by: Valentin Kiselev <mrexox@evilmartians.com>
  • Loading branch information
mrexox authored Aug 8, 2022
1 parent 26e8888 commit 3b176a9
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 49 deletions.
10 changes: 6 additions & 4 deletions docs/full_guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -573,17 +573,19 @@ source_dir_local: ".lefthook-local"

You can manage the verbosity using the `skip_output` config.

Possible values are `meta,success,failure,summary`.
Possible values are `meta,success,failure,summary,execution`.

This config quiets all outputs except failures:

```yml
# lefthook.yml
skip_output:
- meta
- success
- summary
- meta # Skips lefthook version printing
- summary # Skips summary block (successful and failed steps) printing
- success # Skips successful steps printing
- failure # Skips failed steps printing
- execution # Skips printing successfully executed commands and their output (but still prints failed executions)
```

You can also do this with an environment variable:
Expand Down
44 changes: 12 additions & 32 deletions internal/lefthook/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,9 @@ import (

const (
envEnabled = "LEFTHOOK" // "0", "false"
envSkipOutput = "LEFTHOOK_QUIET" // "pre-commit,post-commit"

skipMeta = 0b0001
skipSuccess = 0b0010
skipFailure = 0b0100
skipSummary = 0b1000
envSkipOutput = "LEFTHOOK_QUIET" // "meta,success,failure,summary,execution"
)

type skipOutputSettings int8

func (s skipOutputSettings) doSkip(option int8) bool {
return int8(s)&option != 0
}

func Run(opts *Options, hookName string, gitArgs []string) error {
lefthook, err := initialize(opts)
if err != nil {
Expand Down Expand Up @@ -60,25 +49,16 @@ func (l *Lefthook) Run(hookName string, gitArgs []string) error {
cfg.SkipOutput = append(cfg.SkipOutput, strings.Split(tags, ",")...)
}

var outputSettings skipOutputSettings
for _, param := range cfg.SkipOutput {
switch param {
case "meta":
outputSettings |= skipMeta
case "success":
outputSettings |= skipSuccess
case "failure":
outputSettings |= skipFailure
case "summary":
outputSettings |= skipSummary
}
var logSettings log.SkipSettings
for _, skipOption := range cfg.SkipOutput {
(&logSettings).ApplySetting(skipOption)
}

if cfg.Colors != config.DefaultColorsEnabled {
log.SetColors(cfg.Colors)
}

if !outputSettings.doSkip(skipMeta) {
if !logSettings.SkipMeta() {
log.Info(log.Cyan("Lefthook v" + version.Version(false)))
}

Expand All @@ -90,7 +70,7 @@ Run 'lefthook install' manually.`,
)
}

if !outputSettings.doSkip(skipMeta) {
if !logSettings.SkipMeta() {
log.Info(log.Cyan("RUNNING HOOK:"), log.Bold(hookName))
}

Expand All @@ -105,7 +85,7 @@ Run 'lefthook install' manually.`,

startTime := time.Now()
resultChan := make(chan runner.Result, len(hook.Commands)+len(hook.Scripts))
run := runner.NewRunner(l.Fs, l.repo, hook, gitArgs, resultChan)
run := runner.NewRunner(l.Fs, l.repo, hook, gitArgs, resultChan, logSettings)

go func() {
run.RunAll(
Expand All @@ -120,8 +100,8 @@ Run 'lefthook install' manually.`,
results = append(results, res)
}

if !outputSettings.doSkip(skipSummary) {
printSummary(time.Since(startTime), results, outputSettings)
if !logSettings.SkipSummary() {
printSummary(time.Since(startTime), results, logSettings)
}

for _, result := range results {
Expand All @@ -136,7 +116,7 @@ Run 'lefthook install' manually.`,
func printSummary(
duration time.Duration,
results []runner.Result,
outputSettings skipOutputSettings,
logSettings log.SkipSettings,
) {
if len(results) == 0 {
log.Info(log.Cyan("\nSUMMARY: (SKIP EMPTY)"))
Expand All @@ -147,7 +127,7 @@ func printSummary(
fmt.Sprintf("\nSUMMARY: (done in %.2f seconds)", duration.Seconds()),
))

if !outputSettings.doSkip(skipSuccess) {
if !logSettings.SkipSuccess() {
for _, result := range results {
if result.Status != runner.StatusOk {
continue
Expand All @@ -157,7 +137,7 @@ func printSummary(
}
}

if !outputSettings.doSkip(skipFailure) {
if !logSettings.SkipFailure() {
for _, result := range results {
if result.Status != runner.StatusErr {
continue
Expand Down
33 changes: 20 additions & 13 deletions internal/lefthook/runner/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@ const (
)

type Runner struct {
fs afero.Fs
repo *git.Repository
hook *config.Hook
args []string
failed bool
resultChan chan Result
exec Executor
fs afero.Fs
repo *git.Repository
hook *config.Hook
args []string
failed bool
resultChan chan Result
exec Executor
logSettings log.SkipSettings
}

func NewRunner(
Expand All @@ -40,14 +41,16 @@ func NewRunner(
hook *config.Hook,
args []string,
resultChan chan Result,
logSettings log.SkipSettings,
) *Runner {
return &Runner{
fs: fs,
repo: repo,
hook: hook,
args: args,
resultChan: resultChan,
exec: CommandExecutor{},
fs: fs,
repo: repo,
hook: hook,
args: args,
resultChan: resultChan,
exec: CommandExecutor{},
logSettings: logSettings,
}
}

Expand Down Expand Up @@ -340,6 +343,10 @@ func (r *Runner) run(name, root, failText string, args []string) {
}

if out != nil {
if err == nil && r.logSettings.SkipExecution() {
return
}

log.Infof("%s\n%s\n", execName, out)
} else if err != nil {
log.Infof("%s\n%s\n", execName, err)
Expand Down
50 changes: 50 additions & 0 deletions internal/log/skip_settings.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package log

const (
skipMeta = 1 << iota
skipSuccess
skipFailure
skipSummary
skipExecution
)

type SkipSettings int8

func (s *SkipSettings) ApplySetting(setting string) {
switch setting {
case "meta":
*s |= skipMeta
case "success":
*s |= skipSuccess
case "failure":
*s |= skipFailure
case "summary":
*s |= skipSummary
case "execution":
*s |= skipExecution
}
}

func (s SkipSettings) SkipSuccess() bool {
return s.doSkip(skipSuccess)
}

func (s SkipSettings) SkipFailure() bool {
return s.doSkip(skipFailure)
}

func (s SkipSettings) SkipSummary() bool {
return s.doSkip(skipSummary)
}

func (s SkipSettings) SkipMeta() bool {
return s.doSkip(skipMeta)
}

func (s SkipSettings) SkipExecution() bool {
return s.doSkip(skipExecution)
}

func (s SkipSettings) doSkip(option int8) bool {
return int8(s)&option != 0
}
63 changes: 63 additions & 0 deletions internal/log/skip_settings_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package log

import (
"fmt"
"testing"
)

func TestSkipSetting(t *testing.T) {
for i, tt := range [...]struct {
settings []string
results map[string]bool
}{
{
settings: []string{},
results: map[string]bool{},
},
{
settings: []string{"failure", "execution"},
results: map[string]bool{
"failure": true,
"execution": true,
},
},
{
settings: []string{"meta", "summary", "success", "failure", "execution"},
results: map[string]bool{
"meta": true,
"summary": true,
"success": true,
"failure": true,
"execution": true,
},
},
} {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
var settings SkipSettings

for _, option := range tt.settings {
(&settings).ApplySetting(option)
}

if settings.SkipMeta() != tt.results["meta"] {
t.Errorf("expected SkipMeta to be %v", tt.results["meta"])
}

if settings.SkipSuccess() != tt.results["success"] {
t.Errorf("expected SkipSuccess to be %v", tt.results["success"])
}

if settings.SkipFailure() != tt.results["failure"] {
t.Errorf("expected SkipFailure to be %v", tt.results["failure"])
}

if settings.SkipSummary() != tt.results["summary"] {
t.Errorf("expected SkipSummary to be %v", tt.results["summary"])
}

if settings.SkipExecution() != tt.results["execution"] {
t.Errorf("expected SkipExecution to be %v", tt.results["execution"])
}
})
}
}

0 comments on commit 3b176a9

Please sign in to comment.