formatter.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package formatter
  2. import (
  3. "bytes"
  4. "fmt"
  5. "io"
  6. "strings"
  7. "text/tabwriter"
  8. "text/template"
  9. "github.com/docker/docker/utils/templates"
  10. )
  11. const (
  12. tableFormatKey = "table"
  13. rawFormatKey = "raw"
  14. defaultQuietFormat = "{{.ID}}"
  15. )
  16. // Context contains information required by the formatter to print the output as desired.
  17. type Context struct {
  18. // Output is the output stream to which the formatted string is written.
  19. Output io.Writer
  20. // Format is used to choose raw, table or custom format for the output.
  21. Format string
  22. // Quiet when set to true will simply print minimal information.
  23. Quiet bool
  24. // Trunc when set to true will truncate the output of certain fields such as Container ID.
  25. Trunc bool
  26. // internal element
  27. table bool
  28. finalFormat string
  29. header string
  30. buffer *bytes.Buffer
  31. }
  32. func (c *Context) preformat() {
  33. c.finalFormat = c.Format
  34. if strings.HasPrefix(c.Format, tableKey) {
  35. c.table = true
  36. c.finalFormat = c.finalFormat[len(tableKey):]
  37. }
  38. c.finalFormat = strings.Trim(c.finalFormat, " ")
  39. r := strings.NewReplacer(`\t`, "\t", `\n`, "\n")
  40. c.finalFormat = r.Replace(c.finalFormat)
  41. }
  42. func (c *Context) parseFormat() (*template.Template, error) {
  43. tmpl, err := templates.Parse(c.finalFormat)
  44. if err != nil {
  45. c.buffer.WriteString(fmt.Sprintf("Template parsing error: %v\n", err))
  46. c.buffer.WriteTo(c.Output)
  47. }
  48. return tmpl, err
  49. }
  50. func (c *Context) postformat(tmpl *template.Template, subContext subContext) {
  51. if c.table {
  52. if len(c.header) == 0 {
  53. // if we still don't have a header, we didn't have any containers so we need to fake it to get the right headers from the template
  54. tmpl.Execute(bytes.NewBufferString(""), subContext)
  55. c.header = subContext.fullHeader()
  56. }
  57. t := tabwriter.NewWriter(c.Output, 20, 1, 3, ' ', 0)
  58. t.Write([]byte(c.header))
  59. t.Write([]byte("\n"))
  60. c.buffer.WriteTo(t)
  61. t.Flush()
  62. } else {
  63. c.buffer.WriteTo(c.Output)
  64. }
  65. }
  66. func (c *Context) contextFormat(tmpl *template.Template, subContext subContext) error {
  67. if err := tmpl.Execute(c.buffer, subContext); err != nil {
  68. c.buffer = bytes.NewBufferString(fmt.Sprintf("Template parsing error: %v\n", err))
  69. c.buffer.WriteTo(c.Output)
  70. return err
  71. }
  72. if c.table && len(c.header) == 0 {
  73. c.header = subContext.fullHeader()
  74. }
  75. c.buffer.WriteString("\n")
  76. return nil
  77. }