-
Notifications
You must be signed in to change notification settings - Fork 162
/
stage.go
85 lines (70 loc) · 2.03 KB
/
stage.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
package ui
import (
"time"
"code.cloudfoundry.org/clock"
biuifmt "github.com/cloudfoundry/bosh-cli/ui/fmt"
boshlog "github.com/cloudfoundry/bosh-utils/logger"
)
type Stage interface {
Perform(name string, closure func() error) error
PerformComplex(name string, closure func(Stage) error) error
}
type stage struct {
ui UI
timeService clock.Clock
logTag string
logger boshlog.Logger
simpleMode bool
}
func NewStage(ui UI, timeService clock.Clock, logger boshlog.Logger) Stage {
return &stage{
ui: ui,
timeService: timeService,
logTag: "stage",
logger: logger,
simpleMode: true,
}
}
func (s *stage) Perform(name string, closure func() error) error {
if !s.simpleMode {
// enter simple mode (only line break if exiting complex mode)
s.ui.BeginLinef("\n")
s.simpleMode = true
}
s.ui.BeginLinef("%s...", name)
startTime := s.timeService.Now()
err := closure()
if err != nil {
if skipErr, ok := err.(SkipStageError); ok {
s.ui.EndLinef(" Skipped [%s] (%s)", skipErr.SkipMessage(), s.elapsedSince(startTime))
s.logger.Info(s.logTag, "Skipped stage '%s': %s", name, skipErr.Error())
return nil
}
s.ui.EndLinef(" Failed (%s)", s.elapsedSince(startTime))
return err
}
s.ui.EndLinef(" Finished (%s)", s.elapsedSince(startTime))
return nil
}
func (s *stage) PerformComplex(name string, closure func(Stage) error) error {
// exit simple mode (always line break when entering a new complex stage)
s.ui.BeginLinef("\n")
s.simpleMode = false
s.ui.BeginLinef("Started %s\n", name)
startTime := s.timeService.Now()
err := closure(s.newSubStage())
if err != nil {
s.ui.BeginLinef("Failed %s (%s)\n", name, s.elapsedSince(startTime))
return err
}
s.ui.BeginLinef("Finished %s (%s)\n", name, s.elapsedSince(startTime))
return nil
}
func (s *stage) elapsedSince(startTime time.Time) string {
stopTime := s.timeService.Now()
duration := stopTime.Sub(startTime)
return biuifmt.Duration(duration)
}
func (s *stage) newSubStage() Stage {
return NewStage(NewIndentingUI(s.ui), s.timeService, s.logger)
}