diff options
-rw-r--r-- | repository/tree_entry.go | 72 | ||||
-rw-r--r-- | repository/tree_entry_test.go | 34 |
2 files changed, 106 insertions, 0 deletions
diff --git a/repository/tree_entry.go b/repository/tree_entry.go new file mode 100644 index 00000000..486c4a74 --- /dev/null +++ b/repository/tree_entry.go @@ -0,0 +1,72 @@ +package repository + +import ( + "fmt" + "github.com/MichaelMure/git-bug/util" + "github.com/pkg/errors" + "strings" +) + +type TreeEntry struct { + ObjectType ObjectType + Hash util.Hash + Name string +} + +type ObjectType int + +const ( + Unknown ObjectType = iota + Blob + Tree +) + +func ParseTreeEntry(line string) (TreeEntry, error) { + fields := strings.Fields(line) + + if len(fields) < 4 { + return TreeEntry{}, errors.New("Invalid input to parse as a TreeEntry") + } + + objType, err := ParseObjectType(fields[0], fields[1]) + + if err != nil { + return TreeEntry{}, err + } + + hash := util.Hash(fields[2]) + name := strings.Join(fields[3:], "") + + return TreeEntry{ + ObjectType: objType, + Hash: hash, + Name: name, + }, nil +} + +// Format the entry as a git ls-tree compatible line +func (entry TreeEntry) Format() string { + return fmt.Sprintf("%s %s\t%s\n", entry.ObjectType.Format(), entry.Hash, entry.Name) +} + +func (ot ObjectType) Format() string { + switch ot { + case Blob: + return "100644 blob" + case Tree: + return "040000 tree" + default: + panic("Unknown git object type") + } +} + +func ParseObjectType(mode, objType string) (ObjectType, error) { + switch { + case mode == "100644" && objType == "blob": + return Blob, nil + case mode == "040000" && objType == "tree": + return Tree, nil + default: + return Unknown, errors.Errorf("Unknown git object type %s %s", mode, objType) + } +} diff --git a/repository/tree_entry_test.go b/repository/tree_entry_test.go new file mode 100644 index 00000000..f798a8a9 --- /dev/null +++ b/repository/tree_entry_test.go @@ -0,0 +1,34 @@ +package repository + +import ( + "github.com/MichaelMure/git-bug/util" + "testing" +) + +func TestTreeEntryFormat(t *testing.T) { + + entries := []TreeEntry{ + {Blob, util.Hash("a85730cf5287d40a1e32d3a671ba2296c73387cb"), "name"}, + {Tree, util.Hash("a85730cf5287d40a1e32d3a671ba2296c73387cb"), "name"}, + } + + for _, entry := range entries { + _ = entry.Format() + } +} + +func TestTreeEntryParse(t *testing.T) { + lines := []string{ + "100644 blob 1e5ffaffc67049635ba7b01f77143313503f1ca1 .gitignore", + "040000 tree 728421fea4168b874bc1a8aa409d6723ef445a4e bug", + } + + for _, line := range lines { + _, err := ParseTreeEntry(line) + + if err != nil { + t.Fatal(err) + } + } + +} |