Skip to content

Commit

Permalink
feature: Allow following output (evilmartians#397)
Browse files Browse the repository at this point in the history
  • Loading branch information
mrexox committed Dec 14, 2022
1 parent b376e43 commit 319d8d4
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 111 deletions.
24 changes: 24 additions & 0 deletions docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
- [`files`](#files-global)
- [`parallel`](#parallel)
- [`piped`](#piped)
- [`follow`](#follow)
- [`exclude_tags`](#exclude_tags)
- [`commands`](#commands)
- [`scripts`](#scripts)
Expand Down Expand Up @@ -339,6 +340,29 @@ database:
run: rake db:seed
```

### `follow`

**Default: `false`**

Follow the STDOUT of the running commands and scripts.

**Example**

```yml
# lefthook.yml

pre-push:
follow: true
commands:
backend-tests:
run: bundle exec rspec
frontend-tests:
run: yarn test
```

**Notes**

If used with [`parallel`](#parallel) the output can be a mess, so please avoid setting both options to `true`.

### `exclude_tags`

Expand Down
1 change: 1 addition & 0 deletions internal/config/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type Hook struct {
Piped bool `mapstructure:"piped"`
ExcludeTags []string `mapstructure:"exclude_tags"`
Skip interface{} `mapstructure:"skip"`
Follow bool `mapstructure:"follow"`
}

func (h *Hook) Validate() error {
Expand Down
16 changes: 9 additions & 7 deletions internal/lefthook/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,13 +103,15 @@ Run 'lefthook install' manually.`,
resultChan := make(chan runner.Result, len(hook.Commands)+len(hook.Scripts))

run := runner.NewRunner(
l.Fs,
l.repo,
hook,
gitArgs,
resultChan,
logSettings,
cfg.NoTTY || args.NoTTY,
runner.Opts{
Fs: l.Fs,
Repo: l.repo,
Hook: hook,
GitArgs: gitArgs,
ResultChan: resultChan,
SkipSettings: logSettings,
DisableTTY: cfg.NoTTY || args.NoTTY,
},
)

sourceDirs := []string{
Expand Down
11 changes: 4 additions & 7 deletions internal/lefthook/runner/execute_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import (

type CommandExecutor struct{}

func (e CommandExecutor) Execute(opts ExecuteOptions) (*bytes.Buffer, error) {
func (e CommandExecutor) Execute(opts ExecuteOptions, out io.Writer) error {
stdin := os.Stdin
if opts.interactive && !isatty.IsTerminal(os.Stdin.Fd()) {
tty, err := os.Open("/dev/tty")
Expand All @@ -47,33 +47,30 @@ func (e CommandExecutor) Execute(opts ExecuteOptions) (*bytes.Buffer, error) {

command.Env = append(os.Environ(), envList...)

var out *bytes.Buffer

if opts.interactive {
command.Stdout = os.Stdout
command.Stdin = stdin
command.Stderr = os.Stderr
err := command.Start()
if err != nil {
return nil, err
return err
}
} else {
p, err := pty.Start(command)
if err != nil {
return nil, err
return err
}

defer func() { _ = p.Close() }()

go func() { _, _ = io.Copy(p, stdin) }()

out = bytes.NewBuffer(make([]byte, 0))
_, _ = io.Copy(out, p)
}

defer func() { _ = command.Process.Kill() }()

return out, command.Wait()
return command.Wait()
}

func (e CommandExecutor) RawExecute(command string, args ...string) (*bytes.Buffer, error) {
Expand Down
11 changes: 5 additions & 6 deletions internal/lefthook/runner/execute_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package runner
import (
"bytes"
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
Expand All @@ -12,7 +13,7 @@ import (

type CommandExecutor struct{}

func (e CommandExecutor) Execute(opts ExecuteOptions) (*bytes.Buffer, error) {
func (e CommandExecutor) Execute(opts ExecuteOptions, out io.Writer) error {
command := exec.Command(opts.args[0])
command.SysProcAttr = &syscall.SysProcAttr{
CmdLine: strings.Join(opts.args, " "),
Expand All @@ -31,24 +32,22 @@ func (e CommandExecutor) Execute(opts ExecuteOptions) (*bytes.Buffer, error) {

command.Env = append(os.Environ(), envList...)

var out bytes.Buffer

if opts.interactive {
command.Stdout = os.Stdout
} else {
command.Stdout = &out
command.Stdout = out
}

command.Stdin = os.Stdin
command.Stderr = os.Stderr
err := command.Start()
if err != nil {
return nil, err
return err
}

defer func() { _ = command.Process.Kill() }()

return &out, command.Wait()
return command.Wait()
}

func (e CommandExecutor) RawExecute(command string, args ...string) (*bytes.Buffer, error) {
Expand Down
3 changes: 2 additions & 1 deletion internal/lefthook/runner/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package runner

import (
"bytes"
"io"
)

// ExecutorOptions contains the options that control the execution.
Expand All @@ -15,6 +16,6 @@ type ExecuteOptions struct {
// Executor provides an interface for command execution.
// It is used here for testing purpose mostly.
type Executor interface {
Execute(opts ExecuteOptions) (*bytes.Buffer, error)
Execute(opts ExecuteOptions, out io.Writer) error
RawExecute(command string, args ...string) (*bytes.Buffer, error)
}
Loading

0 comments on commit 319d8d4

Please sign in to comment.