Skip to content

Commit 2f6194b

Browse files
committed
feat: adds task trail as prefix for each log line
1 parent 18ca17f commit 2f6194b

File tree

3 files changed

+33
-196
lines changed

3 files changed

+33
-196
lines changed

examples/Runfile.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ tasks:
119119
- echo "Hello World"
120120

121121
first-second-and-cmds:all-parallel:
122-
# parallel: true
122+
parallel: true
123123
cmd:
124124
- run: first-and-second
125125
- echo "Hello World"

runner/run-task.go

Lines changed: 32 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import (
44
// "bytes"
55
"context"
66
"fmt"
7-
"io"
87
"os"
98
"os/exec"
109
"path/filepath"
@@ -58,230 +57,74 @@ type CreateCommandGroupArgs struct {
5857
Runfile *types.ParsedRunfile
5958
Task *types.ParsedTask
6059

61-
Prefix string
60+
Trail []string
6261

63-
Stdout io.Writer
64-
Stderr io.Writer
62+
Stdout *LogWriter
63+
Stderr *LogWriter
6564
}
6665

67-
func createCommandGroups(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, stdout *LogWriter, stderr *LogWriter) ([]executor.CommandGroup, error) {
66+
func createCommandGroups(ctx Context, args CreateCommandGroupArgs) ([]executor.CommandGroup, error) {
6867
var cmds []executor.CommandGroup
6968

70-
for _, cmd := range pt.Commands {
69+
for _, cmd := range args.Task.Commands {
7170
switch {
7271
case cmd.Run != nil:
7372
{
74-
rt, ok := prf.Tasks[*cmd.Run]
73+
rt, ok := args.Runfile.Tasks[*cmd.Run]
7574
if !ok {
7675
return nil, fmt.Errorf("invalid run target")
7776
}
7877

79-
rtp, err := parser.ParseTask(ctx, prf, rt)
78+
rtp, err := parser.ParseTask(ctx, args.Runfile, rt)
8079
if err != nil {
81-
return nil, errors.WithErr(err).KV("env-vars", prf.Env)
80+
return nil, errors.WithErr(err).KV("env-vars", args.Runfile.Env)
8281
}
8382

84-
rtCommands, err := createCommandGroups(ctx, prf, rtp, stdout, stderr)
83+
rtCommands, err := createCommandGroups(ctx, CreateCommandGroupArgs{
84+
Runfile: args.Runfile,
85+
Task: rtp,
86+
Trail: append(append([]string{}, args.Trail...), rtp.Name),
87+
Stdout: args.Stdout,
88+
Stderr: args.Stderr,
89+
})
8590
if err != nil {
86-
return nil, errors.WithErr(err).KV("env-vars", prf.Env)
91+
return nil, errors.WithErr(err).KV("env-vars", args.Runfile.Env)
8792
}
8893

8994
cg := executor.CommandGroup{
9095
Groups: rtCommands,
9196
Parallel: rtp.Parallel,
9297
}
93-
//
94-
// logger := ctx.With("run", *cmd.Run)
95-
// logger.Info("got", "len(cg.Commands)", len(cg.Commands), "len(cg.Groups)", len(cg.Groups))
96-
cmds = append(cmds, cg)
9798

98-
// cmds = append(cmds, rtCommands...)
99-
100-
// ctx.Debug("HERE", "commands", len(cg.Commands), "run", *cmd.Run)
101-
// cg.Parallel = rtp.Parallel
99+
cmds = append(cmds, cg)
102100
}
103101

104102
case cmd.Command != nil:
105103
{
106-
cg := executor.CommandGroup{Parallel: pt.Parallel}
104+
cg := executor.CommandGroup{Parallel: args.Task.Parallel}
107105

108106
cg.Commands = append(cg.Commands, func(c context.Context) *exec.Cmd {
109107
return CreateCommand(ctx, CmdArgs{
110-
Shell: pt.Shell,
111-
Env: fn.ToEnviron(pt.Env),
108+
Shell: args.Task.Shell,
109+
Env: fn.ToEnviron(args.Task.Env),
112110
Cmd: *cmd.Command,
113-
WorkingDir: pt.WorkingDir,
114-
interactive: pt.Interactive,
115-
Stdout: stdout.WithPrefix(pt.Name),
116-
Stderr: stdout.WithPrefix(pt.Name),
111+
WorkingDir: args.Task.WorkingDir,
112+
interactive: args.Task.Interactive,
113+
Stdout: args.Stdout.WithPrefix(strings.Join(args.Trail, "/")),
114+
Stderr: args.Stderr.WithPrefix(strings.Join(args.Trail, "/")),
117115
})
118116
})
119117

120-
ctx.Debug("HERE", "cmd", *cmd.Command, "parallel", pt.Parallel)
118+
ctx.Debug("HERE", "cmd", *cmd.Command, "parallel", args.Task.Parallel)
121119

122120
cmds = append(cmds, cg)
123121
}
124122
}
125-
126-
// cmds = append(cmds, cg)
127123
}
128124

129125
return cmds, nil
130126
}
131127

132-
// func runCommand(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, args runTaskArgs, command types.ParsedCommandJson) error {
133-
// ctx.Debug("running command task", "command.run", command.Runs, "parent.task", args.taskName)
134-
// if command.If != nil && !*command.If {
135-
// ctx.Debug("skipping execution for failed `if`", "command", command.Runs)
136-
// return nil
137-
// }
138-
//
139-
// if command.Runs != nil {
140-
// for _, run := range command.Runs {
141-
// rt, ok := prf.Tasks[run]
142-
// if !ok {
143-
// return fmt.Errorf("invalid run target")
144-
// }
145-
//
146-
// rtp, err := parser.ParseTask(ctx, prf, rt)
147-
// if err != nil {
148-
// return errors.WithErr(err).KV("env-vars", prf.Env)
149-
// }
150-
//
151-
// if err := runTaskCommands(ctx, prf, rtp, args); err != nil {
152-
// return errors.WithErr(err).KV("env-vars", prf.Env)
153-
// }
154-
// return nil
155-
// }
156-
// }
157-
//
158-
// // stdoutR, stdoutW := io.Pipe()
159-
// // stderrR, stderrW := io.Pipe()
160-
//
161-
// // wg := sync.WaitGroup{}
162-
//
163-
// // [snippet source](https://rderik.com/blog/identify-if-output-goes-to-the-terminal-or-is-being-redirected-in-golang/)
164-
// // stdout, _ := os.Stdout.Stat()
165-
// // stderr, _ := os.Stderr.Stat()
166-
// // isTTY := ((stdout.Mode() & os.ModeCharDevice) == os.ModeCharDevice) && ((stderr.Mode() & os.ModeCharDevice) == os.ModeCharDevice)
167-
// //
168-
// // if isTTY {
169-
// // go func() {
170-
// // defer wg.Done()
171-
// // logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
172-
// // processOutput(os.Stdout, stdoutR, &logPrefix)
173-
// //
174-
// // stderrPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
175-
// // processOutput(os.Stderr, stderrR, &stderrPrefix)
176-
// // }()
177-
// // } else {
178-
// // wg.Add(1)
179-
// // go func() {
180-
// // defer wg.Done()
181-
// // logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s]", strings.Join(trail, "/"))))
182-
// // processOutput(os.Stdout, stdoutR, &logPrefix)
183-
// // // if pt.Interactive {
184-
// // // processOutput(os.Stdout, stdoutR, &logPrefix)
185-
// // // return
186-
// // // }
187-
// // // processOutputLineByLine(os.Stdout, stdoutR, &logPrefix)
188-
// // }()
189-
// //
190-
// // wg.Add(1)
191-
// // go func() {
192-
// // defer wg.Done()
193-
// // logPrefix := fmt.Sprintf("%s ", ctx.theme.TaskPrefixStyle.Render(fmt.Sprintf("[%s/stderr]", strings.Join(trail, "/"))))
194-
// // processOutput(os.Stderr, stderrR, &logPrefix)
195-
// // // if pt.Interactive {
196-
// // // processOutput(os.Stderr, stderrR, &logPrefix)
197-
// // // return
198-
// // // }
199-
// // // processOutputLineByLine(os.Stderr, stderrR, &logPrefix)
200-
// // }()
201-
// // }
202-
//
203-
// if isTTY() {
204-
// borderColor := "#4388cc"
205-
// if !isDarkTheme() {
206-
// borderColor = "#3d5485"
207-
// }
208-
// s := lipgloss.NewStyle().BorderForeground(lipgloss.Color(borderColor)).PaddingLeft(1).PaddingRight(1).Border(lipgloss.RoundedBorder(), true, true, true, true)
209-
// // labelStyle := lipgloss.NewStyle().Foreground(lipgloss.Color(borderColor)).Blink(true)
210-
//
211-
// if args.DebugEnv {
212-
// fmt.Printf("%s\n", s.Render(padString(fmt.Sprintf("%+v", prf.Env), "DEBUG: env")))
213-
// }
214-
//
215-
// hlCode := new(bytes.Buffer)
216-
// // choose colorschemes from `https://swapoff.org/chroma/playground/`
217-
// colorscheme := "catppuccin-macchiato"
218-
// if !isDarkTheme() {
219-
// colorscheme = "monokailight"
220-
// }
221-
// // quick.Highlight(hlCode, strings.TrimSpace(command.Command), "bash", "terminal16m", colorscheme)
222-
//
223-
// for i := range command.Commands {
224-
// cmdStr := strings.TrimSpace(command.Commands[i])
225-
//
226-
// quick.Highlight(hlCode, cmdStr, "bash", "terminal16m", colorscheme)
227-
// // cst := styles.Get("gruvbox")
228-
// // fmt.Println("cst: ", cst.Name, styles.Fallback.Name, styles.Names())
229-
//
230-
// // fmt.Printf("%s\n", s.Render(args.taskName+" | "+hlCode.String()))
231-
// fmt.Printf("%s\n", s.Render(padString(hlCode.String(), args.taskName)))
232-
// }
233-
// }
234-
//
235-
// // logger2 := logging.New(logging.Options{
236-
// // Prefix: "[runfile]",
237-
// // Writer: os.Stderr,
238-
// // SlogKeyAsPrefix: "task",
239-
// // })
240-
//
241-
// // ex := executor.NewCmdExecutor(ctx, executor.CmdExecutorArgs{
242-
// // Logger: logger2,
243-
// // Interactive: pt.Interactive,
244-
// // Commands: func(c context.Context) []*exec.Cmd {
245-
// // commands := make([]*exec.Cmd, 0, len(command.Commands))
246-
// // for i := range command.Commands {
247-
// // commands = append(commands, CreateCommand(c, CmdArgs{
248-
// // Shell: pt.Shell,
249-
// // Env: fn.ToEnviron(pt.Env),
250-
// // Cmd: command.Commands[i],
251-
// // WorkingDir: pt.WorkingDir,
252-
// // interactive: pt.Interactive,
253-
// // Stdout: os.Stdout,
254-
// // Stderr: os.Stderr,
255-
// // }))
256-
// // }
257-
// // return commands
258-
// // },
259-
// // })
260-
// //
261-
// // wg.Add(1)
262-
// // go func() {
263-
// // defer wg.Done()
264-
// // <-ctx.Done()
265-
// // ex.Stop()
266-
// // }()
267-
// //
268-
// // if err := ex.Start(); err != nil {
269-
// // return errors.ErrTaskFailed.Wrap(err).KV("task", args.taskName)
270-
// // }
271-
//
272-
// return nil
273-
// }
274-
275-
// func runTaskCommands(ctx Context, prf *types.ParsedRunfile, pt *types.ParsedTask, args runTaskArgs) error {
276-
// for _, command := range pt.Commands {
277-
// if err := runCommand(ctx, prf, pt, args, command); err != nil {
278-
// return err
279-
// }
280-
// }
281-
//
282-
// return nil
283-
// }
284-
285128
func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
286129
runfilePath := prf.Metadata.RunfilePath
287130
task := prf.Tasks[args.taskName]
@@ -309,7 +152,13 @@ func runTask(ctx Context, prf *types.ParsedRunfile, args runTaskArgs) error {
309152

310153
logStdout := &LogWriter{w: os.Stdout}
311154

312-
execCommands, err := createCommandGroups(ctx, prf, pt, logStdout, logStdout)
155+
execCommands, err := createCommandGroups(ctx, CreateCommandGroupArgs{
156+
Runfile: prf,
157+
Task: pt,
158+
Trail: []string{pt.Name},
159+
Stdout: logStdout,
160+
Stderr: logStdout,
161+
})
313162
if err != nil {
314163
return err
315164
}

runner/writer.go

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,23 +47,11 @@ func (s *LogWriter) Wait() {
4747
s.wg.Wait()
4848
}
4949

50-
func copyBytes(prefix string, src []byte) []byte {
51-
dest := make([]byte, 0, len(src))
52-
for i := range src {
53-
if i == 0 || src[i-1] == '\n' {
54-
dest = append(dest, []byte(fmt.Sprintf("[%s] ", prefix))...)
55-
}
56-
dest = append(dest, src[i])
57-
}
58-
return dest
59-
}
60-
6150
func copyStream(prefix string, dest io.Writer, src io.Reader) {
6251
r := bufio.NewReader(src)
6352
for {
6453
b, err := r.ReadBytes('\n')
6554
if err != nil {
66-
// logger.Info("stdout", "msg", string(msg[:n]), "err", err)
6755
fmt.Println("ERR: ", err)
6856
if errors.Is(err, io.EOF) {
6957
dest.Write([]byte(fmt.Sprintf("[%s] ", prefix)))

0 commit comments

Comments
 (0)