text.go

v0.4.0
Doc Versions Source
1
// Package report provides human-facing implementations of the legatus Reporter
2
// and Prompter interfaces: a text progress reporter and CLI/auto prompters.
3
// These are the injectable interactivity/progress impls (PC2): self-contained,
4
// no globals, no direct os.Stdin/os.Stdout access — all I/O flows through the
5
// configured readers and writers.
6
package report
7
8
import (
9
	"fmt"
10
	"io"
11
12
	"go.bigb.es/auxilia/legatus"
13
)
14
15
var _ legatus.Reporter = (*TextReporter)(nil)
16
17
// TextReporter writes per-step progress lines and a final summary to W. When
18
// Color is set, glyphs are wrapped in ANSI color codes.
19
type TextReporter struct {
20
	W     io.Writer
21
	Color bool
22
}
23
24
// ANSI color codes used when Color is enabled.
25
const (
26
	ansiReset  = "\x1b[0m"
27
	ansiGreen  = "\x1b[32m"
28
	ansiYellow = "\x1b[33m"
29
	ansiRed    = "\x1b[31m"
30
)
31
32
// FlowStart announces the start of a flow on a host.
33
func (r *TextReporter) FlowStart(host, flow string) {
34
	fmt.Fprintf(r.W, "%s: flow %s\n", host, flow)
35
}
36
37
// StepStart announces a step about to run on a host.
38
func (r *TextReporter) StepStart(host, step string) {
39
	fmt.Fprintf(r.W, "%s:   %s ...\n", host, step)
40
}
41
42
// StepDone reports the outcome of a step with a status glyph.
43
func (r *TextReporter) StepDone(host string, res legatus.StepResult) {
44
	glyph := r.glyph(res.Status)
45
	if res.Err != nil {
46
		fmt.Fprintf(r.W, "%s:   %s %s (%s): %v\n", host, glyph, res.Step, res.Status, res.Err)
47
		return
48
	}
49
	fmt.Fprintf(r.W, "%s:   %s %s (%s)\n", host, glyph, res.Step, res.Status)
50
}
51
52
// FlowDone reports the aggregate status of a flow on a host.
53
func (r *TextReporter) FlowDone(host string, res legatus.FlowResult) {
54
	fmt.Fprintf(r.W, "%s: flow %s done (%s)\n", host, res.Flow, res.Status)
55
}
56
57
// RunDone writes the final tally across all hosts.
58
func (r *TextReporter) RunDone(res legatus.RunResult) {
59
	ok, changed, skipped, failed := res.Counts()
60
	fmt.Fprintf(r.W, "ok=%d changed=%d skipped=%d failed=%d\n", ok, changed, skipped, failed)
61
}
62
63
// glyph maps a status to its display glyph, applying ANSI color when enabled.
64
func (r *TextReporter) glyph(s legatus.Status) string {
65
	var g, c string
66
	switch s {
67
	case legatus.StatusChanged, legatus.StatusWouldChange, legatus.StatusOK:
68
		g, c = "✓", ansiGreen
69
	case legatus.StatusSkipped:
70
		g, c = "→", ansiYellow
71
	case legatus.StatusFailed:
72
		g, c = "✗", ansiRed
73
	default:
74
		g, c = "?", ""
75
	}
76
	if r.Color && c != "" {
77
		return c + g + ansiReset
78
	}
79
	return g
80
}
81

Source Files