-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcommand-module.go
More file actions
108 lines (90 loc) · 2.19 KB
/
Copy pathcommand-module.go
File metadata and controls
108 lines (90 loc) · 2.19 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package framework
import (
"context"
"fmt"
"os"
"os/exec"
"strings"
"time"
"github.com/fatih/color"
)
type CommandModule[State any] struct {
Command []string `yaml:"command"`
Dir string `yaml:"dir"`
Env []string `yaml:"env"`
DependsOn []string `yaml:"dependencies"`
Verbose bool `yaml:"verbose"`
Live bool `yaml:"live"`
// ErrorOnOutput controls whether the module should fail if any output was produced by the command.
// This can be helpful for tools like `deadcode`.
ErrorOnOutput bool `yaml:"error_on_output"`
}
func (m *CommandModule[State]) Start(ctx context.Context, _ *State) error {
str := strings.Join(m.Command, " ")
args := make([]string, 0, len(m.Command)-1)
for _, s := range m.Command[1:] {
args = append(args, os.ExpandEnv(s))
}
cmd := exec.CommandContext(ctx, m.Command[0], args...)
cmd.Dir = m.Dir
cmd.Env = append(os.Environ(), m.Env...)
if m.Verbose {
fmt.Printf(
"%s %s %s\n",
color.BlueString("↪︎"),
GetModuleName(ctx),
color.BlackString("starting..."),
)
}
start := time.Now()
var out []byte
var err error
if m.Live {
cmd.Stdout = NewPrefixedWriter(os.Stdout, color.BlackString("[%s] ", GetModuleName(ctx)))
cmd.Stderr = NewPrefixedWriter(os.Stderr, color.BlackString("[%s] ", GetModuleName(ctx)))
err = cmd.Run()
} else {
out, err = cmd.CombinedOutput()
}
duration := time.Since(start).Round(time.Millisecond).String()
if m.ErrorOnOutput && err == nil && len(out) > 0 {
err = fmt.Errorf("unexpected output (%d bytes)", len(out))
}
if err != nil {
fmt.Printf(
"%s %s %s\n",
color.RedString("❌"),
GetModuleName(ctx),
color.BlackString(duration),
)
} else {
fmt.Printf(
"%s %s %s\n",
color.GreenString("✓"),
GetModuleName(ctx),
color.BlackString(duration),
)
}
if m.Verbose {
color.Black("$ %s", str)
}
if err != nil {
if !m.Verbose {
color.Black("$ %s", str)
}
color.Red(err.Error())
fmt.Println(string(out))
} else if len(out) > 0 {
if m.Verbose {
fmt.Println()
color.Black(string(out))
}
}
if m.Verbose {
fmt.Println()
}
return err
}
func (m *CommandModule[State]) Dependencies(context.Context) []string {
return m.DependsOn
}