diff options
author | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-09-25 18:02:45 +0300 |
---|---|---|
committer | Tiago Botelho <tiagonbotelho@hotmail.com> | 2018-09-27 14:58:42 +0300 |
commit | 6ba3498a2c96f947ff37909980ae4a4afb3c8562 (patch) | |
tree | 5a52bc587a3f98d2b61a36c28329196ad7cd1572 /internal/git/lstree | |
parent | 46e6eae9951b7c1740e518a22d04f41bb9a69eae (diff) |
Bumps gitaly-proto version
Diffstat (limited to 'internal/git/lstree')
-rw-r--r-- | internal/git/lstree/last_commits.go | 49 | ||||
-rw-r--r-- | internal/git/lstree/last_commits_test.go | 120 | ||||
-rw-r--r-- | internal/git/lstree/testdata/z-lstree-irregular.txt | bin | 0 -> 191 bytes |
3 files changed, 106 insertions, 63 deletions
diff --git a/internal/git/lstree/last_commits.go b/internal/git/lstree/last_commits.go index c51a33678..09c9c9d96 100644 --- a/internal/git/lstree/last_commits.go +++ b/internal/git/lstree/last_commits.go @@ -3,18 +3,20 @@ package lstree import ( "bufio" "bytes" - "fmt" + "errors" "io" ) -type objectType int +// Enum for the type of object in an ls-tree entry +// can be tree, blob or commit +type ObjectType int // Entry represents a single ls-tree entry type Entry struct { - Mode []byte - Type objectType - Object string - Path string + Mode []byte + Type ObjectType + Oid string + Path string } // Entries holds every ls-tree Entry @@ -26,12 +28,14 @@ type Parser struct { } const ( - delimiter = 0 - tree objectType = iota + 1 + tree ObjectType = iota blob submodule ) +// ErrParse is returned when the parse of an entry was unsuccessful +var ErrParse = errors.New("Failed to parse git ls-tree response") + func (e Entries) Len() int { return len(e) } @@ -55,39 +59,40 @@ func NewParser(src io.Reader) *Parser { // NextEntry reads from git ls-tree --z --full-name command // parses the tree entry and returns a *Entry. func (p *Parser) NextEntry() (*Entry, error) { - result := &Entry{} - - data, err := p.reader.ReadBytes(delimiter) + data, err := p.reader.ReadBytes(0x00) if err != nil { return nil, err } // We expect each `data` to be <mode> SP <type> SP <object> TAB <path>\0. split := bytes.SplitN(data, []byte(" "), 3) - objectAndFile := bytes.SplitN(split[len(split)-1], []byte(" \t"), 2) - split = append(split[:len(split)-1], objectAndFile...) + if len(split) != 3 { + return nil, ErrParse + } - if len(split) != 4 { - return nil, fmt.Errorf("error parsing %q", data) + objectAndFile := bytes.SplitN(split[len(split)-1], []byte("\t"), 2) + parsedEntry := append(split[:len(split)-1], objectAndFile...) + if len(parsedEntry) != 4 { + return nil, ErrParse } - objectType, err := toEnum(string(split[1])) + objectType, err := toEnum(string(parsedEntry[1])) if err != nil { return nil, err } - result.Mode = split[0] + result := &Entry{} + result.Mode = parsedEntry[0] result.Type = objectType - result.Object = string(split[2]) + result.Oid = string(parsedEntry[2]) // We know that the last byte in 'path' will be a zero byte. - path := split[3] - result.Path = string(path[:len(path)-1]) + result.Path = string(bytes.TrimRight(parsedEntry[3], "\x00")) return result, nil } -func toEnum(s string) (objectType, error) { +func toEnum(s string) (ObjectType, error) { switch s { case "tree": return tree, nil @@ -96,6 +101,6 @@ func toEnum(s string) (objectType, error) { case "commit": return submodule, nil default: - return -1, fmt.Errorf("Error in objectType conversion %q", s) + return -1, ErrParse } } diff --git a/internal/git/lstree/last_commits_test.go b/internal/git/lstree/last_commits_test.go index 6bb402743..38b1c5bdb 100644 --- a/internal/git/lstree/last_commits_test.go +++ b/internal/git/lstree/last_commits_test.go @@ -9,54 +9,92 @@ import ( ) func TestParser(t *testing.T) { - file, err := os.Open("testdata/z-lstree.txt") - - require.NoError(t, err) - defer file.Close() - - var parsedEntries Entries - - parser := NewParser(file) - - for { - entry, err := parser.NextEntry() - if err == io.EOF { - break - } - - require.NoError(t, err) - parsedEntries = append(parsedEntries, entry) - } - - expectedEntries := Entries{ + testCases := []struct { + desc string + filename string + entries Entries + }{ { - Mode: []byte("100644"), - Type: 1, - Object: "b78f2bdd90e85de463bd091622efcc70489de893", - Path: ".gitmodules", + desc: "regular entries", + filename: "testdata/z-lstree.txt", + entries: Entries{ + { + Mode: []byte("100644"), + Type: 1, + Oid: "b78f2bdd90e85de463bd091622efcc70489de893", + Path: ".gitmodules", + }, + { + Mode: []byte("040000"), + Type: 0, + Oid: "85ecfbd13807e6374407ba97d252bfe0cf2403fe", + Path: "_locales", + }, + { + Mode: []byte("160000"), + Type: 2, + Oid: "b2291647b9346873501cedf482270495cd85b7b9", + Path: "bar", + }, + }, }, { - Mode: []byte("040000"), - Type: 0, - Object: "85ecfbd13807e6374407ba97d252bfe0cf2403fe", - Path: "_locales", - }, - { - Mode: []byte("160000"), - Type: 2, - Object: "b2291647b9346873501cedf482270495cd85b7b9", - Path: "bar", + desc: "irregular path", + filename: "testdata/z-lstree-irregular.txt", + entries: Entries{ + { + Mode: []byte("100644"), + Type: 1, + Oid: "b78f2bdd90e85de463bd091622efcc70489de893", + Path: ".gitmodules", + }, + { + Mode: []byte("040000"), + Type: 0, + Oid: "85ecfbd13807e6374407ba97d252bfe0cf2403fe", + Path: "_locales", + }, + { + Mode: []byte("160000"), + Type: 2, + Oid: "b2291647b9346873501cedf482270495cd85b7b9", + Path: "foo bar", + }, + }, }, } - require.Equal(t, len(expectedEntries), len(parsedEntries)) + for _, testCase := range testCases { + t.Run(testCase.desc, func(t *testing.T) { + file, err := os.Open(testCase.filename) + + require.NoError(t, err) + defer file.Close() + + parsedEntries := Entries{} + + parser := NewParser(file) + for { + entry, err := parser.NextEntry() + if err == io.EOF { + break + } + + require.NoError(t, err) + parsedEntries = append(parsedEntries, *entry) + } + + expectedEntries := testCase.entries + require.Equal(t, len(expectedEntries), len(parsedEntries)) - for index, parsedEntry := range parsedEntries { - expectedEntry := expectedEntries[index] + for index, parsedEntry := range parsedEntries { + expectedEntry := expectedEntries[index] - require.Equal(t, expectedEntry.Mode, parsedEntry.Mode) - require.Equal(t, expectedEntry.Type, parsedEntry.Type) - require.Equal(t, expectedEntry.Object, parsedEntry.Object) - require.Equal(t, expectedEntry.Path, parsedEntry.Path) + require.Equal(t, expectedEntry.Mode, parsedEntry.Mode) + require.Equal(t, expectedEntry.Type, parsedEntry.Type) + require.Equal(t, expectedEntry.Oid, parsedEntry.Oid) + require.Equal(t, expectedEntry.Path, parsedEntry.Path) + } + }) } } diff --git a/internal/git/lstree/testdata/z-lstree-irregular.txt b/internal/git/lstree/testdata/z-lstree-irregular.txt Binary files differnew file mode 100644 index 000000000..2e506668b --- /dev/null +++ b/internal/git/lstree/testdata/z-lstree-irregular.txt |