Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZeger-Jan van de Weg <git@zjvandeweg.nl>2020-06-03 15:45:14 +0300
committerZeger-Jan van de Weg <git@zjvandeweg.nl>2020-06-19 15:55:02 +0300
commite3b1d6e5d2379977de477a2614f960d4f19e6dea (patch)
treedcb8a1fa5018815d598b4b46b3ab150af8f30619
parent779ca4726b48a426243bac59562b599c7d55ee46 (diff)
lines.Send() takes SenderOpts for grouping options
The lines.Send() allows for a command to be passed in, so the output can be split based on a delimiter. To control what would be send to the client this package will be extended to allow for pagination and limits. The lines.Send() function than would read from the passed in io.Reader, and write to the sink passed as `lines.Sender`, and the logic that alters the execution between these would be send as part of the SenderOpts struct. A small test was added, mostly to force compilation of the package when running `go test`, as well as unit test coverage.
-rw-r--r--internal/helper/lines/send.go29
-rw-r--r--internal/helper/lines/send_test.go25
-rw-r--r--internal/service/ref/refs.go8
-rw-r--r--internal/service/repository/search_files.go2
4 files changed, 49 insertions, 15 deletions
diff --git a/internal/helper/lines/send.go b/internal/helper/lines/send.go
index 4414344d0..d46672c18 100644
--- a/internal/helper/lines/send.go
+++ b/internal/helper/lines/send.go
@@ -6,6 +6,10 @@ import (
"io"
)
+type SenderOpts struct {
+ Delimiter []byte
+}
+
// ItemsPerMessage establishes the threshold to flush the buffer when using the
// `Send` function. It's a variable instead of a constant to make it possible to
// override in tests.
@@ -15,9 +19,9 @@ var ItemsPerMessage = 20
type Sender func([][]byte) error
type writer struct {
- sender Sender
- lines [][]byte
- delim []byte
+ sender Sender
+ lines [][]byte
+ options SenderOpts
}
// CopyAndAppend adds a newly allocated copy of `e` to the `s` slice. Useful to
@@ -67,14 +71,14 @@ func (w *writer) consume(r io.Reader) error {
for {
// delim can be multiple bytes, so we read till the end byte of it ...
- chunk, err := buf.ReadBytes(w.delim[len(w.delim)-1])
+ chunk, err := buf.ReadBytes(w.delimiter()[len(w.delimiter())-1])
if err != nil && err != io.EOF {
return err
}
line = append(line, chunk...)
// ... then we check if the last bytes of line are the same as delim
- if bytes.HasSuffix(line, w.delim) {
+ if bytes.HasSuffix(line, w.delimiter()) {
break
}
@@ -84,7 +88,7 @@ func (w *writer) consume(r io.Reader) error {
}
}
- line = bytes.TrimRight(line, string(w.delim))
+ line = bytes.TrimRight(line, string(w.delimiter()))
if len(line) == 0 {
break
}
@@ -97,12 +101,15 @@ func (w *writer) consume(r io.Reader) error {
return w.flush()
}
-// Send reads output from `r`, splits it at `delim`, then handles the buffered lines using `sender`.
-func Send(r io.Reader, sender Sender, delim []byte) error {
- if len(delim) == 0 {
- delim = []byte{'\n'}
+func (w *writer) delimiter() []byte { return w.options.Delimiter }
+
+// Send reads output from `r`, splits it at `opts.Delimiter``, then handles the
+// buffered lines using `sender`.
+func Send(r io.Reader, sender Sender, opts SenderOpts) error {
+ if len(opts.Delimiter) == 0 {
+ opts.Delimiter = []byte{'\n'}
}
- writer := &writer{sender: sender, delim: delim}
+ writer := &writer{sender: sender, options: opts}
return writer.consume(r)
}
diff --git a/internal/helper/lines/send_test.go b/internal/helper/lines/send_test.go
new file mode 100644
index 000000000..8e880fdea
--- /dev/null
+++ b/internal/helper/lines/send_test.go
@@ -0,0 +1,25 @@
+package lines
+
+import (
+ "bytes"
+ "testing"
+
+ "github.com/stretchr/testify/require"
+)
+
+func TestLinesSend(t *testing.T) {
+ reader := bytes.NewBufferString("mepmep foo bar")
+
+ var out [][]byte
+ sender := func(in [][]byte) error { out = in; return nil }
+ err := Send(reader, sender, SenderOpts{Delimiter: []byte(" ")})
+ require.NoError(t, err)
+
+ expected := [][]byte{
+ []byte("mepmep"),
+ []byte("foo"),
+ []byte("bar"),
+ }
+
+ require.Equal(t, expected, out)
+}
diff --git a/internal/service/ref/refs.go b/internal/service/ref/refs.go
index c4a8e831f..381236c5c 100644
--- a/internal/service/ref/refs.go
+++ b/internal/service/ref/refs.go
@@ -32,8 +32,10 @@ var (
)
type findRefsOpts struct {
- cmdArgs []git.Option
- delim []byte
+ cmdArgs []git.Option
+ delim []byte
+ pageToken string
+ limit uint32
}
func findRefs(ctx context.Context, writer lines.Sender, repo *gitalypb.Repository, patterns []string, opts *findRefsOpts) error {
@@ -54,7 +56,7 @@ func findRefs(ctx context.Context, writer lines.Sender, repo *gitalypb.Repositor
return err
}
- if err := lines.Send(cmd, writer, opts.delim); err != nil {
+ if err := lines.Send(cmd, writer, lines.SenderOpts{Delimiter: opts.delim}); err != nil {
return err
}
diff --git a/internal/service/repository/search_files.go b/internal/service/repository/search_files.go
index fac6ecbe0..26503f006 100644
--- a/internal/service/repository/search_files.go
+++ b/internal/service/repository/search_files.go
@@ -123,7 +123,7 @@ func (s *server) SearchFilesByName(req *gitalypb.SearchFilesByNameRequest, strea
return stream.Send(&gitalypb.SearchFilesByNameResponse{Files: objs})
}
- return lines.Send(cmd, lr, []byte{'\n'})
+ return lines.Send(cmd, lr, lines.SenderOpts{Delimiter: []byte{'\n'}})
}
type searchFilesRequest interface {