|
@@ -3,33 +3,29 @@ package buggo
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
"fmt"
|
|
"fmt"
|
|
|
|
|
+ "os"
|
|
|
|
|
+ "path/filepath"
|
|
|
|
|
+ "strings"
|
|
|
|
|
|
|
|
"github.com/charmbracelet/lipgloss"
|
|
"github.com/charmbracelet/lipgloss"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-type Bug struct {
|
|
|
|
|
- Title string // The title of the bug in human readable format
|
|
|
|
|
- Description Field // The description of the bug
|
|
|
|
|
- Status Field // The status of the bug
|
|
|
|
|
- Tags VariadicField // A slice of VariadicFields
|
|
|
|
|
- Blockedby VariadicField // A slice of VariadicFields
|
|
|
|
|
- Path string // The path to the bug
|
|
|
|
|
- machineTitle string // The machine parseable bug title
|
|
|
|
|
-}
|
|
|
|
|
|
|
+// Bug Definitions ------------------------------------------------------------
|
|
|
|
|
+// ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
-// A struct representing data that is tied to data on disk
|
|
|
|
|
-type Field struct {
|
|
|
|
|
- Path string
|
|
|
|
|
- Data string
|
|
|
|
|
-}
|
|
|
|
|
|
|
+type Bug struct {
|
|
|
|
|
+ Title string // The title of the bug in human readable format
|
|
|
|
|
+ Description Field // The description of the bug
|
|
|
|
|
+ Status Field // The status of the bug
|
|
|
|
|
+ Tags VariadicField // A slice of VariadicFields
|
|
|
|
|
+ Blockedby VariadicField // A slice of VariadicFields
|
|
|
|
|
+ Path string // The path to the bug
|
|
|
|
|
|
|
|
-// VariadicFields hold lists of Field objects.
|
|
|
|
|
-type VariadicField struct {
|
|
|
|
|
- Path string // The associated path on disk of Fields represented by Variadic Field
|
|
|
|
|
- Fields []Field // The underlying slice of Field objects
|
|
|
|
|
|
|
+ // machineTitle string // The machine parseable bug title
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Renders a bug as text
|
|
// Renders a bug as text
|
|
|
|
|
+// DEPRECATED
|
|
|
func (b Bug) View() string {
|
|
func (b Bug) View() string {
|
|
|
headerStyle := lipgloss.NewStyle().
|
|
headerStyle := lipgloss.NewStyle().
|
|
|
Width(120).
|
|
Width(120).
|
|
@@ -64,8 +60,114 @@ func (b Bug) View() string {
|
|
|
)
|
|
)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-// Parses human readable titles as path
|
|
|
|
|
-func (b *Bug) parseHumanToMachine() string { return "" } // TODO: implement!
|
|
|
|
|
|
|
+// Constrcutor for Bugs
|
|
|
|
|
+func (b Bug) New(title string, status Field, tags VariadicField, blockedby VariadicField, path string) (bug Bug, err error) { // TODO Implement
|
|
|
|
|
+ return Bug{}, err
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Constrcutor for Bugs that loads relevant data from disk
|
|
|
|
|
+func (b Bug) NewFromPath(path string) (bug Bug, err error) {
|
|
|
|
|
+ // Required Fields
|
|
|
|
|
+ description := &Field{Path: "/description"}
|
|
|
|
|
+ status := &Field{Path: "/status"}
|
|
|
|
|
+ requiredFields := []*Field{description, status}
|
|
|
|
|
+
|
|
|
|
|
+ for _, field := range requiredFields {
|
|
|
|
|
+ data, err := readPath(path + field.Path)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return Bug{}, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ field.Data = data
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // Variadic Fields
|
|
|
|
|
+ tags := VariadicField{Path: "/tags"}
|
|
|
|
|
+ blockers := VariadicField{Path: "/blockedby"}
|
|
|
|
|
+
|
|
|
|
|
+ tags, _ = VariadicField.NewFromPath(tags, path)
|
|
|
|
|
+ blockers, _ = VariadicField.NewFromPath(blockers, path)
|
|
|
|
|
+ // we can ignore the errors, as loadVariadicField already gracefully handles
|
|
|
|
|
+ //them.
|
|
|
|
|
+
|
|
|
|
|
+ // title from path
|
|
|
|
|
+ title := parsePathToHuman(path)
|
|
|
|
|
+
|
|
|
|
|
+ return Bug{
|
|
|
|
|
+ Title: title,
|
|
|
|
|
+ Description: *description,
|
|
|
|
|
+ Status: *status,
|
|
|
|
|
+ Tags: tags,
|
|
|
|
|
+ Blockedby: blockers,
|
|
|
|
|
+ Path: path,
|
|
|
|
|
+ }, err
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Field Definitions ----------------------------------------------------------
|
|
|
|
|
+// ----------------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+// A struct representing data that is tied to data on disk
|
|
|
|
|
+type Field struct {
|
|
|
|
|
+ Path string
|
|
|
|
|
+ Data string
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Constructor for Fields
|
|
|
|
|
+func (f Field) New(data string, path string) Field { return Field{Data: data, Path: path} }
|
|
|
|
|
+
|
|
|
|
|
+// VariadicField Definitions --------------------------------------------------
|
|
|
|
|
+// ----------------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+// VariadicFields hold lists of Field objects.
|
|
|
|
|
+type VariadicField struct {
|
|
|
|
|
+ Path string // The associated path on disk of Fields represented by Variadic Field
|
|
|
|
|
+ Fields []Field // The underlying slice of Field objects
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Constructor for VariadicFields
|
|
|
|
|
+func (vf VariadicField) New(fields []Field, path string) VariadicField {
|
|
|
|
|
+ return VariadicField{Fields: fields, Path: path}
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Constructor for VariadicFields that loads relevant data from disk
|
|
|
|
|
+func (vf VariadicField) NewFromPath(pathOnDisk string) (v VariadicField, err error) {
|
|
|
|
|
+ rootPath := pathOnDisk + "/" + vf.Path
|
|
|
|
|
+
|
|
|
|
|
+ files, err := os.ReadDir(rootPath)
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return vf, err
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ for _, file := range files {
|
|
|
|
|
+ data, err := readPath(rootPath + "/" + file.Name())
|
|
|
|
|
+ if err != nil {
|
|
|
|
|
+ return vf, err
|
|
|
|
|
+ }
|
|
|
|
|
+ vf.Fields = append(vf.Fields, Field{Data: data, Path: file.Name()})
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return vf, err
|
|
|
|
|
+}
|
|
|
|
|
|
|
|
-// Parses machine parseable titles as human readable
|
|
|
|
|
-func (b *Bug) parseMachineToHuman() string { return "" } // TODO: implement!
|
|
|
|
|
|
|
+// Util Definitions -----------------------------------------------------------
|
|
|
|
|
+// ----------------------------------------------------------------------------
|
|
|
|
|
+
|
|
|
|
|
+// Parses human readable strings as path strings
|
|
|
|
|
+func parseHumanToPath(humanReadable string) string {
|
|
|
|
|
+ var out string
|
|
|
|
|
+ out = strings.ReplaceAll(humanReadable, "-", "\\replace/")
|
|
|
|
|
+ out = strings.ReplaceAll(out, " ", "-")
|
|
|
|
|
+ out = strings.ReplaceAll(out, "\\replace/", "--")
|
|
|
|
|
+
|
|
|
|
|
+ return out
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+// Parses machine parseable paths as human readable strings
|
|
|
|
|
+func parsePathToHuman(path string) string {
|
|
|
|
|
+ _, last := filepath.Split(filepath.Clean(path))
|
|
|
|
|
+ last = strings.ReplaceAll(last, "--", "\\replace/")
|
|
|
|
|
+ last = strings.ReplaceAll(last, "-", " ")
|
|
|
|
|
+ last = strings.ReplaceAll(last, "\\replace/", "-")
|
|
|
|
|
+
|
|
|
|
|
+ return last
|
|
|
|
|
+}
|