-
Notifications
You must be signed in to change notification settings - Fork 9
/
renderline.go
128 lines (104 loc) · 2.91 KB
/
renderline.go
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright 2022 Namespace Labs Inc; All rights reserved.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
package consolesink
import (
"bytes"
"fmt"
"io"
"time"
"namespacelabs.dev/foundation/internal/console/colors"
"namespacelabs.dev/foundation/internal/text/timefmt"
"namespacelabs.dev/foundation/std/tasks"
)
const StampMilliTZ = "Jan _2 15:04:05.000 MST"
func renderTime(w io.Writer, s colors.Style, t time.Time) {
// XXX using UTC() here to be consistent with zerolog.ConsoleWriter.
str := t.UTC().Format(StampMilliTZ)
fmt.Fprint(w, s.Header.Apply(str), " ")
}
func renderLine(w io.Writer, s colors.Style, li Renderable) {
data := li.Data
if OutputActionID {
fmt.Fprint(w, s.Header.Apply("["+trim(data.ActionID.String(), 12)+"] "))
}
if data.Category != "" {
fmt.Fprint(w, s.LogCategory.Apply("("+data.Category+") "))
}
name := data.HumanReadable
if name == "" {
name = data.Name
}
if li.Cached {
fmt.Fprint(w, s.LogCachedName.Apply(name))
} else {
fmt.Fprint(w, name)
}
if progress := li.Progress; progress != nil && data.State == tasks.ActionRunning {
if p := progress.FormatProgress(); p != "" {
fmt.Fprint(w, " ", s.Progress.Apply(p))
}
}
if data.HumanReadable == "" && len(li.Scope) > 0 {
var ws bytes.Buffer
scope := li.Scope
var origlen int
if len(scope) > 3 {
origlen = len(scope)
scope = scope[:3]
}
for k, pkg := range scope {
if k > 0 {
fmt.Fprint(&ws, " ")
}
fmt.Fprint(&ws, pkg)
}
if origlen > 0 {
fmt.Fprintf(&ws, " and %d more", origlen-len(scope))
}
fmt.Fprintf(w, " %s", s.LogScope.Apply(ws.String()))
}
for _, kv := range li.Serialized {
color := s.LogArgument
if kv.result {
color = s.LogResult
}
fmt.Fprint(w, " ", color.Apply(kv.key+"="), kv.value)
}
if data.Err != nil {
t := tasks.ErrorType(data.Err)
if t == tasks.ErrTypeIsCancelled || t == tasks.ErrTypeIsDependencyFailed {
fmt.Fprint(w, " ", s.LogErrorReason.Apply(string(t)))
} else {
fmt.Fprint(w, " ", s.LogError.Apply("err="), s.LogError.Apply(data.Err.Error()))
}
}
}
func renderCompletedAction(raw io.Writer, s colors.Style, r Renderable) {
if r.Data.State.IsDone() {
renderTime(raw, s, r.Data.Completed)
} else {
renderTime(raw, s, r.Data.Started)
}
renderLine(raw, s, r)
if !r.Data.Started.IsZero() && !r.Cached {
if !r.Data.Started.Equal(r.Data.Created) {
d := r.Data.Started.Sub(r.Data.Created)
if d >= 1*time.Microsecond {
fmt.Fprint(raw, " ", s.Header.Apply("waited="), timefmt.Format(d))
}
}
if r.Data.State.IsDone() {
d := r.Data.Completed.Sub(r.Data.Started)
fmt.Fprint(raw, " ", s.Header.Apply("took="), timefmt.Format(d))
}
}
fmt.Fprintln(raw)
}
func LogAction(w io.Writer, s colors.Style, ev tasks.EventData) {
item := Renderable{
Data: ev,
}
item.precompute(tasks.ResultData{})
renderCompletedAction(w, s, item)
}