bug.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Data and interface definitions for bugs
  2. package buggo
  3. import (
  4. "os"
  5. "path/filepath"
  6. "strings"
  7. )
  8. // Bug Definitions ------------------------------------------------------------
  9. // ----------------------------------------------------------------------------
  10. type Bug struct {
  11. Title string // The title of the bug in human readable format
  12. Description Field // The description of the bug
  13. Status Field // The status of the bug
  14. Tags VariadicField // A slice of VariadicFields
  15. Blockedby VariadicField // A slice of VariadicFields
  16. Path string // The path to the bug
  17. // machineTitle string // The machine parseable bug title
  18. }
  19. // Constrcutor for Bugs
  20. func (b Bug) New(title string, status Field, tags VariadicField, blockedby VariadicField, path string) (bug Bug, err error) { // TODO Implement
  21. return Bug{}, err
  22. }
  23. // Constrcutor for Bugs that loads relevant data from disk
  24. func (b Bug) NewFromPath(path string) (bug Bug, err error) {
  25. // Required Fields
  26. description := &Field{Path: "/description"}
  27. status := &Field{Path: "/status"}
  28. requiredFields := []*Field{description, status}
  29. for _, field := range requiredFields {
  30. data, err := readPath(path + field.Path)
  31. if err != nil {
  32. return Bug{}, err
  33. }
  34. field.Data = data
  35. }
  36. // Variadic Fields
  37. tags := VariadicField{Path: "/tags"}
  38. blockers := VariadicField{Path: "/blockedby"}
  39. tags, _ = VariadicField.NewFromPath(tags, path)
  40. blockers, _ = VariadicField.NewFromPath(blockers, path)
  41. // we can ignore the errors, as loadVariadicField already gracefully handles
  42. //them.
  43. // title from path
  44. title := parsePathToHuman(path)
  45. return Bug{
  46. Title: title,
  47. Description: *description,
  48. Status: *status,
  49. Tags: tags,
  50. Blockedby: blockers,
  51. Path: path,
  52. }, err
  53. }
  54. // Field Definitions ----------------------------------------------------------
  55. // ----------------------------------------------------------------------------
  56. // A struct representing data that is tied to data on disk
  57. type Field struct {
  58. Path string
  59. Data string
  60. }
  61. // Constructor for Fields
  62. func (f Field) New(data string, path string) Field { return Field{Data: data, Path: path} }
  63. // VariadicField Definitions --------------------------------------------------
  64. // ----------------------------------------------------------------------------
  65. // VariadicFields hold lists of Field objects.
  66. type VariadicField struct {
  67. Path string // The associated path on disk of Fields represented by Variadic Field
  68. Fields []Field // The underlying slice of Field objects
  69. }
  70. // Constructor for VariadicFields
  71. func (vf VariadicField) New(fields []Field, path string) VariadicField {
  72. return VariadicField{Fields: fields, Path: path}
  73. }
  74. // Constructor for VariadicFields that loads relevant data from disk
  75. func (vf VariadicField) NewFromPath(pathOnDisk string) (v VariadicField, err error) {
  76. rootPath := pathOnDisk + "/" + vf.Path
  77. files, err := os.ReadDir(rootPath)
  78. if err != nil {
  79. return vf, err
  80. }
  81. for _, file := range files {
  82. data, err := readPath(rootPath + "/" + file.Name())
  83. if err != nil {
  84. return vf, err
  85. }
  86. vf.Fields = append(vf.Fields, Field{Data: data, Path: file.Name()})
  87. }
  88. return vf, err
  89. }
  90. // Util Definitions -----------------------------------------------------------
  91. // ----------------------------------------------------------------------------
  92. // Parses human readable strings as path strings
  93. func parseHumanToPath(humanReadable string) string {
  94. var out string
  95. out = strings.ReplaceAll(humanReadable, "-", "\\replace/")
  96. out = strings.ReplaceAll(out, " ", "-")
  97. out = strings.ReplaceAll(out, "\\replace/", "--")
  98. return out
  99. }
  100. // Parses machine parseable paths as human readable strings
  101. func parsePathToHuman(path string) string {
  102. _, last := filepath.Split(filepath.Clean(path))
  103. last = strings.ReplaceAll(last, "--", "\\replace/")
  104. last = strings.ReplaceAll(last, "-", " ")
  105. last = strings.ReplaceAll(last, "\\replace/", "-")
  106. return last
  107. }