Skip to content

Commit 6f25fc9

Browse files
Refactor colorize/colorizef functions
Introduce constants for color names. Simplify setup of `colorize` and `colorizef`. Signed-off-by: Rachel Sheikh <[email protected]> Co-authored-by: Matthias Diester <[email protected]>
1 parent 2a19f16 commit 6f25fc9

File tree

5 files changed

+152
-106
lines changed

5 files changed

+152
-106
lines changed

box.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import (
2727
"io"
2828
"strings"
2929

30-
colorful "github.com/lucasb-eyer/go-colorful"
30+
"github.com/lucasb-eyer/go-colorful"
3131

3232
"github.com/gonvenience/bunt"
3333
"github.com/gonvenience/term"

errors_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ var _ = Describe("error rendering", func() {
4848
Context("rendering errors", func() {
4949
It("should render a context error using a box", func() {
5050
cause := fmt.Errorf("failed to load X and Y")
51-
err := fmt.Errorf("unable to start Z: %w",cause)
51+
err := fmt.Errorf("unable to start Z: %w", cause)
5252

5353
Expect(SprintError(err)).To(
5454
BeEquivalentTo(ContentBox(

output.go

Lines changed: 78 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,29 +26,66 @@ import (
2626
"fmt"
2727
"strings"
2828

29-
colorful "github.com/lucasb-eyer/go-colorful"
3029
yamlv2 "gopkg.in/yaml.v2"
3130
yamlv3 "gopkg.in/yaml.v3"
3231

32+
"github.com/lucasb-eyer/go-colorful"
33+
3334
"github.com/gonvenience/bunt"
3435
)
3536

37+
// frequently used output constants
38+
const (
39+
colorAnchor = "anchorColor"
40+
colorBinary = "binaryColor"
41+
colorBool = "boolColor"
42+
colorComment = "commentColor"
43+
colorDash = "dashColor"
44+
colorFloat = "floatColor"
45+
colorIndentLine = "indentLineColor"
46+
colorInt = "intColor"
47+
colorKey = "keyColor"
48+
colorMultiLineText = "multiLineTextColor"
49+
colorNull = "nullColor"
50+
colorScalarDefault = "scalarDefaultColor"
51+
)
52+
53+
const (
54+
documentStart = "documentStart"
55+
emptyStructures = "emptyStructures"
56+
)
57+
58+
const (
59+
emptyList = "[]"
60+
emptyObject = "{}"
61+
)
62+
63+
const (
64+
nodeTagBinary = "!!binary"
65+
nodeTagBool = "!!bool"
66+
nodeTagFloat = "!!float"
67+
nodeTagInt = "!!int"
68+
nodeTagNull = "!!null"
69+
nodeTagString = "!!str"
70+
nodeTagTime = "!!timestamp"
71+
)
72+
3673
// DefaultColorSchema is a prepared usable color schema for the neat output
3774
// processor which is loosly based upon the colors used by Atom
3875
var DefaultColorSchema = map[string]colorful.Color{
39-
"documentStart": bunt.LightSlateGray,
40-
"keyColor": bunt.IndianRed,
41-
"indentLineColor": {R: 0.14, G: 0.14, B: 0.14},
42-
"scalarDefaultColor": bunt.PaleGreen,
43-
"boolColor": bunt.Moccasin,
44-
"floatColor": bunt.Orange,
45-
"intColor": bunt.MediumPurple,
46-
"multiLineTextColor": bunt.Aquamarine,
47-
"nullColor": bunt.DarkOrange,
48-
"binaryColor": bunt.Aqua,
49-
"emptyStructures": bunt.PaleGoldenrod,
50-
"commentColor": bunt.DimGray,
51-
"anchorColor": bunt.CornflowerBlue,
76+
documentStart: bunt.LightSlateGray,
77+
colorKey: bunt.IndianRed,
78+
colorIndentLine: {R: 0.14, G: 0.14, B: 0.14},
79+
colorScalarDefault: bunt.PaleGreen,
80+
colorBool: bunt.Moccasin,
81+
colorFloat: bunt.Orange,
82+
colorInt: bunt.MediumPurple,
83+
colorMultiLineText: bunt.Aquamarine,
84+
colorNull: bunt.DarkOrange,
85+
colorBinary: bunt.Aqua,
86+
emptyStructures: bunt.PaleGoldenrod,
87+
colorComment: bunt.DimGray,
88+
colorAnchor: bunt.CornflowerBlue,
5289
}
5390

5491
// OutputProcessor provides the functionality to output neat YAML strings using
@@ -81,8 +118,8 @@ func NewOutputProcessor(useIndentLines bool, boldKeys bool, colorSchema *map[str
81118
}
82119
}
83120

84-
// TODO Change signature to swap into the right order, color first, text second
85-
func (p *OutputProcessor) colorize(text string, colorName string) string {
121+
// colorize returns the given string with the color applied via bunt.
122+
func (p *OutputProcessor) colorize(colorName string, text string) string {
86123
if p.colorSchema != nil {
87124
if value, ok := (*p.colorSchema)[colorName]; ok {
88125
return bunt.Style(text, bunt.Foreground(value))
@@ -92,60 +129,64 @@ func (p *OutputProcessor) colorize(text string, colorName string) string {
92129
return text
93130
}
94131

132+
// colorizef formats a string using the provided color name and format string (created via fmt.Sprintf)
133+
// and returns the formatted string with the color applied via bunt.
134+
//
135+
// If additional arguments are not provided, the function skips the fmt.Sprintf call.
95136
func (p *OutputProcessor) colorizef(colorName string, format string, a ...interface{}) string {
96137
if len(a) > 0 {
97-
return p.colorize(fmt.Sprintf(format, a...), colorName)
138+
return p.colorize(colorName, fmt.Sprintf(format, a...))
98139
}
99140

100-
return p.colorize(format, colorName)
141+
return p.colorize(colorName, format)
101142
}
102143

103144
func (p *OutputProcessor) determineColorByType(obj interface{}) string {
104-
color := "scalarDefaultColor"
145+
color := colorScalarDefault
105146

106147
switch t := obj.(type) {
107148
case *yamlv3.Node:
108149
switch t.Tag {
109-
case "!!str":
150+
case nodeTagString:
110151
if len(strings.Split(strings.TrimSpace(t.Value), "\n")) > 1 {
111-
color = "multiLineTextColor"
152+
color = colorMultiLineText
112153
}
113154

114-
case "!!int":
115-
color = "intColor"
155+
case nodeTagInt:
156+
color = colorInt
116157

117-
case "!!float":
118-
color = "floatColor"
158+
case nodeTagFloat:
159+
color = colorFloat
119160

120-
case "!!bool":
121-
color = "boolColor"
161+
case nodeTagBool:
162+
color = colorBool
122163

123-
case "!!null":
124-
color = "nullColor"
164+
case nodeTagNull:
165+
color = colorNull
125166
}
126167

127168
case bool:
128-
color = "boolColor"
169+
color = colorBool
129170

130171
case float32, float64:
131-
color = "floatColor"
172+
color = colorFloat
132173

133174
case int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64, uintptr:
134-
color = "intColor"
175+
color = colorInt
135176

136177
case string:
137178
if len(strings.Split(strings.TrimSpace(t), "\n")) > 1 {
138-
color = "multiLineTextColor"
179+
color = colorMultiLineText
139180
}
140181
}
141182

142183
return color
143184
}
144185

145186
func (p *OutputProcessor) isScalar(obj interface{}) bool {
146-
switch tobj := obj.(type) {
187+
switch tObj := obj.(type) {
147188
case *yamlv3.Node:
148-
return tobj.Kind == yamlv3.ScalarNode
189+
return tObj.Kind == yamlv3.ScalarNode
149190

150191
case yamlv2.MapSlice, []interface{}, []yamlv2.MapSlice:
151192
return false
@@ -166,10 +207,10 @@ func (p *OutputProcessor) simplify(list []yamlv2.MapSlice) []interface{} {
166207

167208
func (p *OutputProcessor) prefixAdd() string {
168209
if p.useIndentLines {
169-
return p.colorize("│ ", "indentLineColor")
210+
return p.colorize(colorIndentLine, "")
170211
}
171212

172-
return p.colorize(" ", "indentLineColor")
213+
return p.colorize(colorIndentLine, " ")
173214
}
174215

175216
func followAlias(node *yamlv3.Node) *yamlv3.Node {

output_json.go

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,7 @@ func (p *OutputProcessor) neatJSONofNode(prefix string, node *yamlv3.Node) error
215215

216216
case yamlv3.MappingNode:
217217
if len(node.Content) == 0 {
218-
fmt.Fprint(p.out, p.colorize("{}", "emptyStructures"))
218+
fmt.Fprint(p.out, p.colorize(emptyStructures, emptyObject))
219219
return nil
220220
}
221221

@@ -225,7 +225,7 @@ func (p *OutputProcessor) neatJSONofNode(prefix string, node *yamlv3.Node) error
225225

226226
fmt.Fprint(p.out,
227227
optionalIndentPrefix(),
228-
p.colorize(`"`+k.Value+`"`, "keyColor"), ": ",
228+
p.colorizef(colorKey, "%q", k.Value), ": ",
229229
)
230230

231231
if p.isScalar(v) {
@@ -249,7 +249,7 @@ func (p *OutputProcessor) neatJSONofNode(prefix string, node *yamlv3.Node) error
249249

250250
case yamlv3.SequenceNode:
251251
if len(node.Content) == 0 {
252-
fmt.Fprint(p.out, p.colorize("[]", "emptyStructures"))
252+
fmt.Fprint(p.out, p.colorize(emptyStructures, emptyList))
253253
return nil
254254
}
255255

@@ -291,8 +291,8 @@ func (p *OutputProcessor) neatJSONofNode(prefix string, node *yamlv3.Node) error
291291
fmt.Fprint(p.out,
292292
prefix,
293293
p.colorize(
294-
string(bytes),
295294
p.determineColorByType(node),
295+
string(bytes),
296296
))
297297
}
298298

@@ -301,7 +301,7 @@ func (p *OutputProcessor) neatJSONofNode(prefix string, node *yamlv3.Node) error
301301

302302
func (p *OutputProcessor) neatJSONofYAMLMapSlice(prefix string, mapslice yamlv2.MapSlice) error {
303303
if len(mapslice) == 0 {
304-
_, _ = p.out.WriteString(p.colorize("{}", "emptyStructures"))
304+
_, _ = p.out.WriteString(p.colorize(emptyStructures, emptyObject))
305305
return nil
306306
}
307307

@@ -312,7 +312,7 @@ func (p *OutputProcessor) neatJSONofYAMLMapSlice(prefix string, mapslice yamlv2.
312312
keyString := fmt.Sprintf("\"%v\": ", mapitem.Key)
313313

314314
_, _ = p.out.WriteString(prefix + p.prefixAdd())
315-
_, _ = p.out.WriteString(p.colorize(keyString, "keyColor"))
315+
_, _ = p.out.WriteString(p.colorize(colorKey, keyString))
316316

317317
if p.isScalar(mapitem.Value) {
318318
if err := p.neatJSONofScalar("", mapitem.Value); err != nil {
@@ -340,7 +340,7 @@ func (p *OutputProcessor) neatJSONofYAMLMapSlice(prefix string, mapslice yamlv2.
340340

341341
func (p *OutputProcessor) neatJSONofSlice(prefix string, list []interface{}) error {
342342
if len(list) == 0 {
343-
_, _ = p.out.WriteString(p.colorize("[]", "emptyStructures"))
343+
_, _ = p.out.WriteString(p.colorize(emptyStructures, emptyList))
344344
return nil
345345
}
346346

@@ -375,7 +375,7 @@ func (p *OutputProcessor) neatJSONofSlice(prefix string, list []interface{}) err
375375

376376
func (p *OutputProcessor) neatJSONofScalar(prefix string, obj interface{}) error {
377377
if obj == nil {
378-
_, _ = p.out.WriteString(p.colorize("null", "nullColor"))
378+
_, _ = p.out.WriteString(p.colorize(colorNull, "null"))
379379
return nil
380380
}
381381

@@ -389,10 +389,10 @@ func (p *OutputProcessor) neatJSONofScalar(prefix string, obj interface{}) error
389389
_, _ = p.out.WriteString(prefix)
390390
parts := strings.Split(string(data), "\\n")
391391
for idx, part := range parts {
392-
_, _ = p.out.WriteString(p.colorize(part, color))
392+
_, _ = p.out.WriteString(p.colorize(color, part))
393393

394394
if idx < len(parts)-1 {
395-
_, _ = p.out.WriteString(p.colorize("\\n", "emptyStructures"))
395+
_, _ = p.out.WriteString(p.colorize(emptyStructures, "\\n"))
396396
}
397397
}
398398

@@ -405,22 +405,22 @@ func cast(node yamlv3.Node) (interface{}, error) {
405405
}
406406

407407
switch node.Tag {
408-
case "!!str":
408+
case nodeTagString:
409409
return node.Value, nil
410410

411-
case "!!timestamp":
411+
case nodeTagTime:
412412
return parseTime(node.Value)
413413

414-
case "!!int":
414+
case nodeTagInt:
415415
return strconv.Atoi(node.Value)
416416

417-
case "!!float":
417+
case nodeTagFloat:
418418
return strconv.ParseFloat(node.Value, 64)
419419

420-
case "!!bool":
420+
case nodeTagBool:
421421
return strconv.ParseBool(node.Value)
422422

423-
case "!!null":
423+
case nodeTagNull:
424424
return nil, nil
425425

426426
default:
@@ -429,17 +429,7 @@ func cast(node yamlv3.Node) (interface{}, error) {
429429
}
430430

431431
func parseTime(value string) (time.Time, error) {
432-
// YAML Spec regarding timestamp: https://yaml.org/type/timestamp.html
433-
var layouts = [...]string{
434-
time.RFC3339,
435-
"2006-01-02T15:04:05.999999999Z",
436-
"2006-01-02t15:04:05.999999999-07:00",
437-
"2006-01-02 15:04:05.999999999 07:00",
438-
"2006-01-02 15:04:05.999999999",
439-
"2006-01-02",
440-
}
441-
442-
for _, layout := range layouts {
432+
for _, layout := range yamlTimeLayouts {
443433
if result, err := time.Parse(layout, value); err == nil {
444434
return result, nil
445435
}

0 commit comments

Comments
 (0)