writer.go 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. package progress
  2. import (
  3. "context"
  4. "sync"
  5. "time"
  6. "github.com/containerd/console"
  7. "github.com/moby/term"
  8. )
  9. // EventStatus indicates the status of an action
  10. type EventStatus int
  11. const (
  12. // Working means that the current task is working
  13. Working EventStatus = iota
  14. // Done means that the current task is done
  15. Done
  16. // Error means that the current task has errored
  17. Error
  18. )
  19. // Event reprensents a progress event
  20. type Event struct {
  21. ID string
  22. Text string
  23. Status EventStatus
  24. StatusText string
  25. Done bool
  26. startTime time.Time
  27. endTime time.Time
  28. spinner *spinner
  29. }
  30. func (e *Event) stop() {
  31. e.endTime = time.Now()
  32. e.spinner.Stop()
  33. }
  34. // Writer can write multiple progress events
  35. type Writer interface {
  36. Start(context.Context) error
  37. Stop()
  38. Event(Event)
  39. }
  40. type writerKey struct{}
  41. // WithContextWriter adds the writer to the context
  42. func WithContextWriter(ctx context.Context, writer Writer) context.Context {
  43. return context.WithValue(ctx, writerKey{}, writer)
  44. }
  45. // ContextWriter returns the writer from the context
  46. func ContextWriter(ctx context.Context) Writer {
  47. s, _ := ctx.Value(writerKey{}).(Writer)
  48. return s
  49. }
  50. // NewWriter returns a new multi-progress writer
  51. func NewWriter(out console.File) (Writer, error) {
  52. _, isTerminal := term.GetFdInfo(out)
  53. if isTerminal {
  54. con, err := console.ConsoleFromFile(out)
  55. if err != nil {
  56. return nil, err
  57. }
  58. return &ttyWriter{
  59. out: con,
  60. eventIDs: []string{},
  61. events: map[string]Event{},
  62. repeated: false,
  63. done: make(chan bool),
  64. mtx: &sync.RWMutex{},
  65. }, nil
  66. }
  67. return &plainWriter{
  68. out: out,
  69. done: make(chan bool),
  70. }, nil
  71. }