Skip to content

Commit e1286f4

Browse files
Basic level-based printer
To print any data/information, this commit implements a custom printer that can be configured with a severity/level to control the verbosity for different purposes. The printer is located in the `pkg/prt` package that provides multiple print formatting functions including some colored prefix symbols/words for each level. This ensures the severity of the output can be recognized at a glance. Epic GH-33 Depends on GH-58 Resolves GH-59
1 parent 84f640f commit e1286f4

File tree

4 files changed

+202
-0
lines changed

4 files changed

+202
-0
lines changed

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,15 @@
55
# Repository: https://github.com/arcticicestudio/snowsaw
66
# License: MIT
77

8+
# +--------------------+
9+
# + JetBrains Products +
10+
# +--------------------+
11+
# +--- IntelliJ IDEA ---+
12+
.idea/*
13+
!.idea/runConfigurations
14+
!.idea/saved-exports
15+
!.idea/watcherTasks.xml
16+
817
# +------+
918
# + Logs +
1019
# +------+

go.mod

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
11
module github.com/arcticicestudio/snowsaw
22

33
go 1.12
4+
5+
require (
6+
github.com/fatih/color v1.7.0
7+
github.com/mattn/go-colorable v0.1.2 // indirect
8+
)

go.sum

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
2+
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
3+
github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
4+
github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
5+
github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
6+
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
7+
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223 h1:DH4skfRX4EBpamg7iV4ZlCpblAHI6s6TDM39bFZumv8=
8+
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=

pkg/prt/printer.go

Lines changed: 180 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,180 @@
1+
// Copyright (C) 2017-present Arctic Ice Studio <[email protected]>
2+
// Copyright (C) 2017-present Sven Greb <[email protected]>
3+
//
4+
// Project: snowsaw
5+
// Repository: https://github.com/arcticicestudio/snowsaw
6+
// License: MIT
7+
8+
// Author: Arctic Ice Studio <[email protected]>
9+
// Author: Sven Greb <[email protected]>
10+
// Since: 0.4.0
11+
12+
// Package prt provides functions to print any data to os.Stdout with a specific level for different purposes.
13+
package prt
14+
15+
import (
16+
"fmt"
17+
"io"
18+
"os"
19+
"strings"
20+
21+
"github.com/fatih/color"
22+
)
23+
24+
// Verbosity defines the detail level of the printer logging behavior.
25+
type Verbosity uint32
26+
27+
type printerConfig struct {
28+
verbosity Verbosity
29+
}
30+
31+
const (
32+
// FatalVerbosity is the level of the printer used to log any data with fatal scope.
33+
FatalVerbosity Verbosity = iota
34+
// ErrorVerbosity is the level of the printer used to log any data with error scope.
35+
ErrorVerbosity
36+
// WarnVerbosity is the level of the printer used to log any data with warn scope.
37+
WarnVerbosity
38+
// SuccessVerbosity is the level of the printer used to log any data with success scope.
39+
SuccessVerbosity
40+
// InfoVerbosity is the level of the printer used to log any data with info scope.
41+
// If no other level is explicitly set this level is used by default.
42+
InfoVerbosity
43+
// DebugVerbosity is the level of the printer used to log any data with debug scope.
44+
DebugVerbosity
45+
)
46+
47+
var p = newPrinterConfig(InfoVerbosity)
48+
49+
// Debugf prints a debug scope message with a prefix symbol using the given format.
50+
// A new line will be appended if not already included in the given format.
51+
func Debugf(format string, args ...interface{}) { p.debugf(format, args...) }
52+
53+
// Errorf prints a error scope message with a prefix symbol using the given format.
54+
// A new line will be appended if not already included in the given format.
55+
func Errorf(format string, args ...interface{}) { p.errorf(format, args...) }
56+
57+
// Fatalf prints a fatal scope message with a prefix symbol using the given format.
58+
// A new line will be appended if not already included in the given format.
59+
func Fatalf(format string, args ...interface{}) { p.fatalf(format, args...) }
60+
61+
// Infof prints a info scope message with a prefix symbol using the given format.
62+
// A new line will be appended if not already included in the given format.
63+
func Infof(format string, args ...interface{}) { p.infof(format, args...) }
64+
65+
// Successf prints a success scope message with a prefix symbol using the given format.
66+
// A new line will be appended if not already included in the given format.
67+
func Successf(format string, args ...interface{}) { p.successf(format, args...) }
68+
69+
// Warnf prints a warning scope message with a prefix symbol using the given format.
70+
// A new line will be appended if not already included in the given format.
71+
func Warnf(format string, args ...interface{}) { p.warnf(format, args...) }
72+
73+
// SetVerbosityLevel sets the logging level of the printer.
74+
func SetVerbosityLevel(v Verbosity) { p.setVerbosityLevel(v) }
75+
76+
// ParseVerbosityLevel takes a logging level name and returns the Verbosity log level constant.
77+
func ParseVerbosityLevel(lvl string) (Verbosity, error) {
78+
switch strings.ToLower(lvl) {
79+
case "fatal":
80+
return FatalVerbosity, nil
81+
case "error":
82+
return ErrorVerbosity, nil
83+
case "warn":
84+
return WarnVerbosity, nil
85+
case "info":
86+
return InfoVerbosity, nil
87+
case "debug":
88+
return DebugVerbosity, nil
89+
}
90+
91+
var v Verbosity
92+
return v, fmt.Errorf("not a valid printer level: %q", lvl)
93+
}
94+
95+
// MarshalText returns the textual representation of itself.
96+
func (v Verbosity) MarshalText() ([]byte, error) {
97+
switch v {
98+
case DebugVerbosity:
99+
return []byte("debug"), nil
100+
case InfoVerbosity:
101+
return []byte("info"), nil
102+
case WarnVerbosity:
103+
return []byte("warn"), nil
104+
case ErrorVerbosity:
105+
return []byte("error"), nil
106+
case FatalVerbosity:
107+
return []byte("fatal"), nil
108+
}
109+
110+
return nil, fmt.Errorf("not a valid printer level %d", v)
111+
}
112+
113+
// Convert the Verbosity to a string.
114+
func (v Verbosity) String() string {
115+
if b, err := v.MarshalText(); err == nil {
116+
return string(b)
117+
} else {
118+
return "unknown"
119+
}
120+
}
121+
122+
// UnmarshalText implements encoding.TextUnmarshaler to unmarshal a textual representation of itself.
123+
func (v *Verbosity) UnmarshalText(text []byte) error {
124+
l, err := ParseVerbosityLevel(string(text))
125+
if err != nil {
126+
return err
127+
}
128+
129+
*v = Verbosity(l)
130+
return nil
131+
}
132+
133+
func newPrinterConfig(v Verbosity) *printerConfig {
134+
return &printerConfig{verbosity: v}
135+
}
136+
137+
func (p *printerConfig) debugf(format string, args ...interface{}) {
138+
prefix := color.New(color.FgMagenta, color.Bold).Sprint("Debug: ")
139+
p.withNewLine(DebugVerbosity, os.Stdout, prefix, format, args...)
140+
}
141+
142+
func (p *printerConfig) errorf(format string, args ...interface{}) {
143+
prefix := color.New(color.FgRed, color.Bold).Sprint("✕ ")
144+
p.withNewLine(ErrorVerbosity, os.Stdout, prefix, format, args...)
145+
}
146+
147+
func (p *printerConfig) fatalf(format string, args ...interface{}) {
148+
prefix := color.New(color.FgRed).Sprint("⭍ ")
149+
p.withNewLine(FatalVerbosity, os.Stdout, prefix, format, args...)
150+
}
151+
152+
func (p *printerConfig) infof(format string, args ...interface{}) {
153+
prefix := color.New(color.FgBlue).Sprint("➜ ")
154+
p.withNewLine(InfoVerbosity, os.Stdout, prefix, format, args...)
155+
}
156+
157+
func (p *printerConfig) successf(format string, args ...interface{}) {
158+
prefix := color.New(color.FgGreen).Sprint("✓ ")
159+
p.withNewLine(SuccessVerbosity, os.Stdout, prefix, format, args...)
160+
}
161+
162+
func (p *printerConfig) warnf(format string, args ...interface{}) {
163+
prefix := color.New(color.FgYellow, color.Bold).Sprint("! ")
164+
p.withNewLine(WarnVerbosity, os.Stdout, prefix, format, args...)
165+
}
166+
167+
// isPrinterEnabled checks if the verbosity of the printer is greater than the verbosity param.
168+
func (p *printerConfig) isPrinterEnabled(v Verbosity) bool { return p.verbosity >= v }
169+
170+
func (p *printerConfig) setVerbosityLevel(v Verbosity) { p.verbosity = v }
171+
172+
// withNewLine writes to the specified writer and appends a new line to the given format if not already.
173+
func (p *printerConfig) withNewLine(v Verbosity, w io.Writer, prefix string, format string, args ...interface{}) {
174+
if p.isPrinterEnabled(v) {
175+
if !strings.HasSuffix(format, "\n") {
176+
format = format + "\n"
177+
}
178+
fmt.Fprintf(w, prefix+format, args...)
179+
}
180+
}

0 commit comments

Comments
 (0)