Skip to content

Commit 29b7a0a

Browse files
committed
refactor(cli/cliui): create stage writer used by provisioner job
1 parent 0a6e644 commit 29b7a0a

File tree

1 file changed

+76
-42
lines changed

1 file changed

+76
-42
lines changed

cli/cliui/provisionerjob.go

Lines changed: 76 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"io"
88
"os"
99
"os/signal"
10+
"strings"
1011
"sync"
1112
"time"
1213

@@ -69,21 +70,20 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
6970
jobMutex sync.Mutex
7071
)
7172

73+
sw := &stageWriter{w: writer, verbose: opts.Verbose, silentLogs: opts.Silent}
74+
7275
printStage := func() {
73-
_, _ = fmt.Fprintf(writer, "==> ⧗ %s\n", currentStage)
76+
sw.Start(currentStage)
7477
}
7578

7679
updateStage := func(stage string, startedAt time.Time) {
7780
if currentStage != "" {
78-
mark := "✔"
81+
duration := startedAt.Sub(currentStageStartedAt)
7982
if job.CompletedAt != nil && job.Status != codersdk.ProvisionerJobSucceeded {
80-
mark = "✘"
81-
}
82-
dur := startedAt.Sub(currentStageStartedAt).Milliseconds()
83-
if dur < 0 {
84-
dur = 0
83+
sw.Fail(currentStage, duration)
84+
} else {
85+
sw.Complete(currentStage, duration)
8586
}
86-
_, _ = fmt.Fprintf(writer, "=== %s %s [%dms]\n", mark, currentStage, dur)
8787
}
8888
if stage == "" {
8989
return
@@ -147,30 +147,15 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
147147
}
148148
defer closer.Close()
149149

150-
var (
151-
// logOutput is where log output is written
152-
logOutput = writer
153-
// logBuffer is where logs are buffered if opts.Silent is true
154-
logBuffer = &bytes.Buffer{}
155-
)
156-
if opts.Silent {
157-
logOutput = logBuffer
158-
}
159-
flushLogBuffer := func() {
160-
if opts.Silent {
161-
_, _ = io.Copy(writer, logBuffer)
162-
}
163-
}
164-
165150
ticker := time.NewTicker(opts.FetchInterval)
166151
defer ticker.Stop()
167152
for {
168153
select {
169154
case err = <-errChan:
170-
flushLogBuffer()
155+
sw.Fail(currentStage, time.Since(currentStageStartedAt))
171156
return err
172157
case <-ctx.Done():
173-
flushLogBuffer()
158+
sw.Fail(currentStage, time.Since(currentStageStartedAt))
174159
return ctx.Err()
175160
case <-ticker.C:
176161
updateJob()
@@ -194,34 +179,83 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
194179
Message: job.Error,
195180
Code: job.ErrorCode,
196181
}
182+
sw.Fail(currentStage, time.Since(currentStageStartedAt))
197183
jobMutex.Unlock()
198-
flushLogBuffer()
199184
return err
200185
}
201186

202-
output := ""
203-
switch log.Level {
204-
case codersdk.LogLevelTrace, codersdk.LogLevelDebug:
205-
if !opts.Verbose {
206-
continue
207-
}
208-
output = DefaultStyles.Placeholder.Render(log.Output)
209-
case codersdk.LogLevelError:
210-
output = DefaultStyles.Error.Render(log.Output)
211-
case codersdk.LogLevelWarn:
212-
output = DefaultStyles.Warn.Render(log.Output)
213-
case codersdk.LogLevelInfo:
214-
output = log.Output
215-
}
216-
217187
jobMutex.Lock()
218188
if log.Stage != currentStage && log.Stage != "" {
219189
updateStage(log.Stage, log.CreatedAt)
220190
jobMutex.Unlock()
221191
continue
222192
}
223-
_, _ = fmt.Fprintf(logOutput, "%s\n", output)
193+
sw.Log(log.CreatedAt, log.Level, log.Output)
224194
jobMutex.Unlock()
225195
}
226196
}
227197
}
198+
199+
type stageWriter struct {
200+
w io.Writer
201+
verbose bool
202+
silentLogs bool
203+
logBuf bytes.Buffer
204+
}
205+
206+
func (s *stageWriter) Start(stage string) {
207+
_, _ = fmt.Fprintf(s.w, " => ⧗ %s\n", stage)
208+
}
209+
210+
func (s *stageWriter) Complete(stage string, duration time.Duration) {
211+
s.end(stage, duration, true)
212+
}
213+
214+
func (s *stageWriter) Fail(stage string, duration time.Duration) {
215+
s.flushLogs()
216+
s.end(stage, duration, false)
217+
}
218+
219+
//nolint:revive
220+
func (s *stageWriter) end(stage string, duration time.Duration, ok bool) {
221+
s.logBuf.Reset()
222+
223+
mark := "✔"
224+
if !ok {
225+
mark = "✘"
226+
}
227+
if duration < 0 {
228+
duration = 0
229+
}
230+
_, _ = fmt.Fprintf(s.w, " == %s %s [%dms]\n", mark, stage, duration.Milliseconds())
231+
}
232+
233+
func (s *stageWriter) Log(createdAt time.Time, level codersdk.LogLevel, line string) {
234+
w := s.w
235+
if s.silentLogs {
236+
w = &s.logBuf
237+
}
238+
239+
render := func(s ...string) string { return strings.Join(s, " ") }
240+
241+
switch level {
242+
case codersdk.LogLevelTrace, codersdk.LogLevelDebug:
243+
if !s.verbose {
244+
return
245+
}
246+
render = DefaultStyles.Placeholder.Render
247+
case codersdk.LogLevelError:
248+
render = DefaultStyles.Error.Render
249+
case codersdk.LogLevelWarn:
250+
render = DefaultStyles.Warn.Render
251+
case codersdk.LogLevelInfo:
252+
}
253+
_, _ = fmt.Fprintf(w, " %s\n", render(fmt.Sprintf("%s %s", createdAt.Local().Format("2006-01-02 15:04:05.000Z07:00"), line)))
254+
}
255+
256+
func (s *stageWriter) flushLogs() {
257+
if s.silentLogs {
258+
_, _ = io.Copy(s.w, &s.logBuf)
259+
}
260+
s.logBuf.Reset()
261+
}

0 commit comments

Comments
 (0)