diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-06-28 09:41:29 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-06-28 09:53:28 +0300 |
commit | 109b4ea6881eada0a94e0188f5dd89178f72836f (patch) | |
tree | f4f5bdedb75179fab6cd5d97258fa7d636b410ad | |
parent | 56aa9a2196f0003bc011e4152bb093b8d32be83d (diff) |
blob: Expose pipeline-related symbols
We're about to move the git-rev-list(1)/git-cat-file(1) pipeline into a
standalone package. In order to prepare for this, this commit already
renames all relevant symbols to be public to make the move easier to
reason about.
-rw-r--r-- | internal/gitaly/service/blob/blobs.go | 40 | ||||
-rw-r--r-- | internal/gitaly/service/blob/lfs_pointers.go | 44 | ||||
-rw-r--r-- | internal/gitaly/service/blob/pipeline.go | 211 | ||||
-rw-r--r-- | internal/gitaly/service/blob/pipeline_test.go | 634 |
4 files changed, 467 insertions, 462 deletions
diff --git a/internal/gitaly/service/blob/blobs.go b/internal/gitaly/service/blob/blobs.go index ce6e1dca9..2ef784790 100644 --- a/internal/gitaly/service/blob/blobs.go +++ b/internal/gitaly/service/blob/blobs.go @@ -58,15 +58,15 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS return helper.ErrInternalf("cannot determine Git version: %v", err) } - var revlistOptions []revlistOption + var revlistOptions []RevlistOption if gitVersion.SupportsObjectTypeFilter() { - revlistOptions = append(revlistOptions, withObjectTypeFilter(objectTypeBlob)) + revlistOptions = append(revlistOptions, WithObjectTypeFilter(ObjectTypeBlob)) } - revlistChan := revlist(ctx, repo, req.GetRevisions(), revlistOptions...) - catfileInfoChan := catfileInfo(ctx, catfileProcess, revlistChan) - catfileInfoChan = catfileInfoFilter(ctx, catfileInfoChan, func(r catfileInfoResult) bool { - return r.objectInfo.Type == "blob" + revlistChan := Revlist(ctx, repo, req.GetRevisions(), revlistOptions...) + catfileInfoChan := CatfileInfo(ctx, catfileProcess, revlistChan) + catfileInfoChan = CatfileInfoFilter(ctx, catfileInfoChan, func(r CatfileInfoResult) bool { + return r.ObjectInfo.Type == "blob" }) // If we have a zero bytes limit, then the caller didn't request any blob contents at all. @@ -74,13 +74,13 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS if req.GetBytesLimit() == 0 { var i uint32 for blob := range catfileInfoChan { - if blob.err != nil { - return helper.ErrInternal(blob.err) + if blob.Err != nil { + return helper.ErrInternal(blob.Err) } if err := chunker.Send(&gitalypb.ListBlobsResponse_Blob{ - Oid: blob.objectInfo.Oid.String(), - Size: blob.objectInfo.Size, + Oid: blob.ObjectInfo.Oid.String(), + Size: blob.ObjectInfo.Size, }); err != nil { return helper.ErrInternal(fmt.Errorf("sending blob chunk: %w", err)) } @@ -91,12 +91,12 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS } } } else { - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) var i uint32 for blob := range catfileObjectChan { - if blob.err != nil { - return helper.ErrInternal(blob.err) + if blob.Err != nil { + return helper.ErrInternal(blob.Err) } headerSent := false @@ -106,8 +106,8 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS } if !headerSent { - message.Oid = blob.objectInfo.Oid.String() - message.Size = blob.objectInfo.Size + message.Oid = blob.ObjectInfo.Oid.String() + message.Size = blob.ObjectInfo.Size headerSent = true } @@ -120,17 +120,17 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS readLimit := req.GetBytesLimit() if readLimit < 0 { - readLimit = blob.objectInfo.Size + readLimit = blob.ObjectInfo.Size } - _, err := io.CopyN(dataChunker, blob.objectReader, readLimit) + _, err := io.CopyN(dataChunker, blob.ObjectReader, readLimit) if err != nil && !errors.Is(err, io.EOF) { return helper.ErrInternal(fmt.Errorf("sending blob data: %w", err)) } // Discard trailing blob data in case the blob is bigger than the read // limit. - _, err = io.Copy(ioutil.Discard, blob.objectReader) + _, err = io.Copy(ioutil.Discard, blob.ObjectReader) if err != nil { return helper.ErrInternal(fmt.Errorf("discarding blob data: %w", err)) } @@ -140,8 +140,8 @@ func (s *server) ListBlobs(req *gitalypb.ListBlobsRequest, stream gitalypb.BlobS // header manually in that case. if !headerSent { if err := chunker.Send(&gitalypb.ListBlobsResponse_Blob{ - Oid: blob.objectInfo.Oid.String(), - Size: blob.objectInfo.Size, + Oid: blob.ObjectInfo.Oid.String(), + Size: blob.ObjectInfo.Size, }); err != nil { return helper.ErrInternal(fmt.Errorf("sending blob chunk: %w", err)) } diff --git a/internal/gitaly/service/blob/lfs_pointers.go b/internal/gitaly/service/blob/lfs_pointers.go index 200377d77..1b500af92 100644 --- a/internal/gitaly/service/blob/lfs_pointers.go +++ b/internal/gitaly/service/blob/lfs_pointers.go @@ -78,17 +78,17 @@ func (s *server) ListLFSPointers(in *gitalypb.ListLFSPointersRequest, stream git return helper.ErrInternalf("cannot determine Git version: %v", err) } - revlistOptions := []revlistOption{withBlobLimit(lfsPointerMaxSize)} + revlistOptions := []RevlistOption{WithBlobLimit(lfsPointerMaxSize)} if gitVersion.SupportsObjectTypeFilter() { - revlistOptions = append(revlistOptions, withObjectTypeFilter(objectTypeBlob)) + revlistOptions = append(revlistOptions, WithObjectTypeFilter(ObjectTypeBlob)) } - revlistChan := revlist(ctx, repo, in.GetRevisions(), revlistOptions...) - catfileInfoChan := catfileInfo(ctx, catfileProcess, revlistChan) - catfileInfoChan = catfileInfoFilter(ctx, catfileInfoChan, func(r catfileInfoResult) bool { - return r.objectInfo.Type == "blob" && r.objectInfo.Size <= lfsPointerMaxSize + revlistChan := Revlist(ctx, repo, in.GetRevisions(), revlistOptions...) + catfileInfoChan := CatfileInfo(ctx, catfileProcess, revlistChan) + catfileInfoChan = CatfileInfoFilter(ctx, catfileInfoChan, func(r CatfileInfoResult) bool { + return r.ObjectInfo.Type == "blob" && r.ObjectInfo.Size <= lfsPointerMaxSize }) - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) if err := sendLFSPointers(chunker, catfileObjectChan, int(in.Limit)); err != nil { return err @@ -146,11 +146,11 @@ func (s *server) ListAllLFSPointers(in *gitalypb.ListAllLFSPointersRequest, stre return helper.ErrInternal(fmt.Errorf("creating catfile process: %w", err)) } - catfileInfoChan := catfileInfoAllObjects(ctx, repo) - catfileInfoChan = catfileInfoFilter(ctx, catfileInfoChan, func(r catfileInfoResult) bool { - return r.objectInfo.Type == "blob" && r.objectInfo.Size <= lfsPointerMaxSize + catfileInfoChan := CatfileInfoAllObjects(ctx, repo) + catfileInfoChan = CatfileInfoFilter(ctx, catfileInfoChan, func(r CatfileInfoResult) bool { + return r.ObjectInfo.Type == "blob" && r.ObjectInfo.Size <= lfsPointerMaxSize }) - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) if err := sendLFSPointers(chunker, catfileObjectChan, int(in.Limit)); err != nil { return err @@ -194,17 +194,17 @@ func (s *server) GetLFSPointers(req *gitalypb.GetLFSPointersRequest, stream gita return helper.ErrInternal(fmt.Errorf("creating catfile process: %w", err)) } - objectChan := make(chan revlistResult, len(req.GetBlobIds())) + objectChan := make(chan RevlistResult, len(req.GetBlobIds())) for _, blobID := range req.GetBlobIds() { - objectChan <- revlistResult{oid: git.ObjectID(blobID)} + objectChan <- RevlistResult{OID: git.ObjectID(blobID)} } close(objectChan) - catfileInfoChan := catfileInfo(ctx, catfileProcess, objectChan) - catfileInfoChan = catfileInfoFilter(ctx, catfileInfoChan, func(r catfileInfoResult) bool { - return r.objectInfo.Type == "blob" && r.objectInfo.Size <= lfsPointerMaxSize + catfileInfoChan := CatfileInfo(ctx, catfileProcess, objectChan) + catfileInfoChan = CatfileInfoFilter(ctx, catfileInfoChan, func(r CatfileInfoResult) bool { + return r.ObjectInfo.Type == "blob" && r.ObjectInfo.Size <= lfsPointerMaxSize }) - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) if err := sendLFSPointers(chunker, catfileObjectChan, 0); err != nil { return err @@ -378,13 +378,13 @@ func (t *lfsPointerSender) Send() error { return t.send(t.pointers) } -func sendLFSPointers(chunker *chunk.Chunker, lfsPointers <-chan catfileObjectResult, limit int) error { +func sendLFSPointers(chunker *chunk.Chunker, lfsPointers <-chan CatfileObjectResult, limit int) error { buffer := bytes.NewBuffer(make([]byte, 0, lfsPointerMaxSize)) var i int for lfsPointer := range lfsPointers { - if lfsPointer.err != nil { - return helper.ErrInternal(lfsPointer.err) + if lfsPointer.Err != nil { + return helper.ErrInternal(lfsPointer.Err) } // Avoid allocating bytes for an LFS pointer until we know the current blob really @@ -394,7 +394,7 @@ func sendLFSPointers(chunker *chunk.Chunker, lfsPointers <-chan catfileObjectRes // Given that we filter pipeline objects by size, the biggest object we may see here // is 200 bytes in size. So it's not much of a problem to read this into memory // completely. - if _, err := io.Copy(buffer, lfsPointer.objectReader); err != nil { + if _, err := io.Copy(buffer, lfsPointer.ObjectReader); err != nil { return helper.ErrInternal(fmt.Errorf("reading LFS pointer data: %w", err)) } @@ -408,7 +408,7 @@ func sendLFSPointers(chunker *chunk.Chunker, lfsPointers <-chan catfileObjectRes if err := chunker.Send(&gitalypb.LFSPointer{ Data: objectData, Size: int64(len(objectData)), - Oid: lfsPointer.objectInfo.Oid.String(), + Oid: lfsPointer.ObjectInfo.Oid.String(), }); err != nil { return helper.ErrInternal(fmt.Errorf("sending LFS pointer chunk: %w", err)) } diff --git a/internal/gitaly/service/blob/pipeline.go b/internal/gitaly/service/blob/pipeline.go index 52500b401..d5aa306c6 100644 --- a/internal/gitaly/service/blob/pipeline.go +++ b/internal/gitaly/service/blob/pipeline.go @@ -14,75 +14,80 @@ import ( "gitlab.com/gitlab-org/gitaly/v14/internal/git/localrepo" ) -// revlistResult is a result for the revlist pipeline step. -type revlistResult struct { - // err is an error which occurred during execution of the pipeline. - err error - - // oid is the object ID of an object printed by git-rev-list(1). - oid git.ObjectID - // objectName is the name of the object. This is typically the path of the object if it was +// RevlistResult is a result for the revlist pipeline step. +type RevlistResult struct { + // Err is an error which occurred during execution of the pipeline. + Err error + + // OID is the object ID of an object printed by git-rev-list(1). + OID git.ObjectID + // ObjectName is the name of the object. This is typically the path of the object if it was // traversed via either a tree or a commit. The path depends on the order in which objects // are traversed: if e.g. two different trees refer to the same blob with different names, // the blob's path depends on which of the trees was traversed first. - objectName []byte + ObjectName []byte } -type objectType string +// ObjectType is a Git object type used for filtering objects. +type ObjectType string const ( - objectTypeCommit = objectType("commit") - objectTypeBlob = objectType("blob") - objectTypeTree = objectType("tree") - objectTypeTag = objectType("tag") + // ObjectTypeCommit is the type of a Git commit. + ObjectTypeCommit = ObjectType("commit") + // ObjectTypeBlob is the type of a Git blob. + ObjectTypeBlob = ObjectType("blob") + // ObjectTypeTree is the type of a Git tree. + ObjectTypeTree = ObjectType("tree") + // ObjectTypeTag is the type of a Git tag. + ObjectTypeTag = ObjectType("tag") ) // revlistConfig is configuration for the revlist pipeline step. type revlistConfig struct { blobLimit int - objectType objectType + objectType ObjectType } -// revlistOption is an option for the revlist pipeline step. -type revlistOption func(cfg *revlistConfig) +// RevlistOption is an option for the revlist pipeline step. +type RevlistOption func(cfg *revlistConfig) -// withBlobLimit sets up a size limit for blobs. Only blobs whose size is smaller than this limit +// WithBlobLimit sets up a size limit for blobs. Only blobs whose size is smaller than this limit // will be returned by the pipeline step. -func withBlobLimit(limit int) revlistOption { +func WithBlobLimit(limit int) RevlistOption { return func(cfg *revlistConfig) { cfg.blobLimit = limit } } -// withObjectTypeFilter will set up a `--filter=object:type=` filter for git-rev-list(1). This will +// WithObjectTypeFilter will set up a `--filter=object:type=` filter for git-rev-list(1). This will // cause it to filter out any objects which do not match the given type. Because git-rev-list(1) by // default never filters provided arguments, this option also sets up the `--filter-provided` flag. // Note that this option is only supported starting with Git v2.32.0 or later. -func withObjectTypeFilter(t objectType) revlistOption { +func WithObjectTypeFilter(t ObjectType) RevlistOption { return func(cfg *revlistConfig) { cfg.objectType = t } } -// revlist runs git-rev-list(1) with objects and object names enabled. The returned channel will +// Revlist runs git-rev-list(1) with objects and object names enabled. The returned channel will // contain all object IDs listed by this command. Cancelling the context will cause the pipeline to // be cancelled, too. -func revlist( +func Revlist( ctx context.Context, repo *localrepo.Repo, revisions []string, - options ...revlistOption, -) <-chan revlistResult { + options ...RevlistOption, +) <-chan RevlistResult { var cfg revlistConfig for _, option := range options { option(&cfg) } - resultChan := make(chan revlistResult) + resultChan := make(chan RevlistResult) go func() { defer close(resultChan) - sendResult := func(result revlistResult) bool { + sendResult := func(result RevlistResult) bool { select { case resultChan <- result: return false @@ -114,7 +119,7 @@ func revlist( Args: revisions, }) if err != nil { - sendResult(revlistResult{err: err}) + sendResult(RevlistResult{Err: err}) return } @@ -127,11 +132,11 @@ func revlist( oidAndName := bytes.SplitN(line, []byte{' '}, 2) - result := revlistResult{ - oid: git.ObjectID(oidAndName[0]), + result := RevlistResult{ + OID: git.ObjectID(oidAndName[0]), } if len(oidAndName) == 2 && len(oidAndName[1]) > 0 { - result.objectName = oidAndName[1] + result.ObjectName = oidAndName[1] } if isDone := sendResult(result); isDone { @@ -140,15 +145,15 @@ func revlist( } if err := scanner.Err(); err != nil { - sendResult(revlistResult{ - err: fmt.Errorf("scanning rev-list output: %w", err), + sendResult(RevlistResult{ + Err: fmt.Errorf("scanning rev-list output: %w", err), }) return } if err := revlist.Wait(); err != nil { - sendResult(revlistResult{ - err: fmt.Errorf("rev-list pipeline command: %w", err), + sendResult(RevlistResult{ + Err: fmt.Errorf("rev-list pipeline command: %w", err), }) return } @@ -157,16 +162,16 @@ func revlist( return resultChan } -// revlistFilter filters the revlistResults from the provided channel with the filter function: if +// RevlistFilter filters the revlistResults from the provided channel with the filter function: if // the filter returns `false` for a given item, then it will be dropped from the pipeline. Errors // cannot be filtered and will always be passed through. -func revlistFilter(ctx context.Context, c <-chan revlistResult, filter func(revlistResult) bool) <-chan revlistResult { - resultChan := make(chan revlistResult) +func RevlistFilter(ctx context.Context, c <-chan RevlistResult, filter func(RevlistResult) bool) <-chan RevlistResult { + resultChan := make(chan RevlistResult) go func() { defer close(resultChan) for result := range c { - if result.err != nil || filter(result) { + if result.Err != nil || filter(result) { select { case resultChan <- result: case <-ctx.Done(): @@ -178,28 +183,28 @@ func revlistFilter(ctx context.Context, c <-chan revlistResult, filter func(revl return resultChan } -// catfileInfoResult is a result for the catfileInfo pipeline step. -type catfileInfoResult struct { - // err is an error which occurred during execution of the pipeline. - err error +// CatfileInfoResult is a result for the CatfileInfo pipeline step. +type CatfileInfoResult struct { + // Err is an error which occurred during execution of the pipeline. + Err error - // objectName is the object name as received from the revlistResultChan. - objectName []byte - // objectInfo is the object info of the object. - objectInfo *catfile.ObjectInfo + // ObjectName is the object name as received from the revlistResultChan. + ObjectName []byte + // ObjectInfo is the object info of the object. + ObjectInfo *catfile.ObjectInfo } -// catfileInfo processes revlistResults from the given channel and extracts object information via +// CatfileInfo processes revlistResults from the given channel and extracts object information via // `git cat-file --batch-check`. The returned channel will contain all processed catfile info // results. Any error received via the channel or encountered in this step will cause the pipeline // to fail. Context cancellation will gracefully halt the pipeline. -func catfileInfo(ctx context.Context, catfile catfile.Batch, revlistResultChan <-chan revlistResult) <-chan catfileInfoResult { - resultChan := make(chan catfileInfoResult) +func CatfileInfo(ctx context.Context, catfile catfile.Batch, revlistResultChan <-chan RevlistResult) <-chan CatfileInfoResult { + resultChan := make(chan CatfileInfoResult) go func() { defer close(resultChan) - sendResult := func(result catfileInfoResult) bool { + sendResult := func(result CatfileInfoResult) bool { select { case resultChan <- result: return false @@ -209,22 +214,22 @@ func catfileInfo(ctx context.Context, catfile catfile.Batch, revlistResultChan < } for revlistResult := range revlistResultChan { - if revlistResult.err != nil { - sendResult(catfileInfoResult{err: revlistResult.err}) + if revlistResult.Err != nil { + sendResult(CatfileInfoResult{Err: revlistResult.Err}) return } - objectInfo, err := catfile.Info(ctx, revlistResult.oid.Revision()) + objectInfo, err := catfile.Info(ctx, revlistResult.OID.Revision()) if err != nil { - sendResult(catfileInfoResult{ - err: fmt.Errorf("retrieving object info for %q: %w", revlistResult.oid, err), + sendResult(CatfileInfoResult{ + Err: fmt.Errorf("retrieving object info for %q: %w", revlistResult.OID, err), }) return } - if isDone := sendResult(catfileInfoResult{ - objectName: revlistResult.objectName, - objectInfo: objectInfo, + if isDone := sendResult(CatfileInfoResult{ + ObjectName: revlistResult.ObjectName, + ObjectInfo: objectInfo, }); isDone { return } @@ -234,18 +239,18 @@ func catfileInfo(ctx context.Context, catfile catfile.Batch, revlistResultChan < return resultChan } -// catfileInfoAllObjects enumerates all Git objects part of the repository's object directory and +// CatfileInfoAllObjects enumerates all Git objects part of the repository's object directory and // extracts their object info via `git cat-file --batch-check`. The returned channel will contain // all processed results. Any error encountered during execution of this pipeline step will cause // the pipeline to fail. Context cancellation will gracefully halt the pipeline. Note that with this // pipeline step, the resulting catfileInfoResults will never have an object name. -func catfileInfoAllObjects(ctx context.Context, repo *localrepo.Repo) <-chan catfileInfoResult { - resultChan := make(chan catfileInfoResult) +func CatfileInfoAllObjects(ctx context.Context, repo *localrepo.Repo) <-chan CatfileInfoResult { + resultChan := make(chan CatfileInfoResult) go func() { defer close(resultChan) - sendResult := func(result catfileInfoResult) bool { + sendResult := func(result CatfileInfoResult) bool { select { case resultChan <- result: return false @@ -264,8 +269,8 @@ func catfileInfoAllObjects(ctx context.Context, repo *localrepo.Repo) <-chan cat }, }) if err != nil { - sendResult(catfileInfoResult{ - err: fmt.Errorf("spawning cat-file failed: %w", err), + sendResult(CatfileInfoResult{ + Err: fmt.Errorf("spawning cat-file failed: %w", err), }) return } @@ -278,22 +283,22 @@ func catfileInfoAllObjects(ctx context.Context, repo *localrepo.Repo) <-chan cat break } - sendResult(catfileInfoResult{ - err: fmt.Errorf("parsing object info: %w", err), + sendResult(CatfileInfoResult{ + Err: fmt.Errorf("parsing object info: %w", err), }) return } - if isDone := sendResult(catfileInfoResult{ - objectInfo: objectInfo, + if isDone := sendResult(CatfileInfoResult{ + ObjectInfo: objectInfo, }); isDone { return } } if err := cmd.Wait(); err != nil { - sendResult(catfileInfoResult{ - err: fmt.Errorf("cat-file failed: %w", err), + sendResult(CatfileInfoResult{ + Err: fmt.Errorf("cat-file failed: %w", err), }) return } @@ -302,16 +307,16 @@ func catfileInfoAllObjects(ctx context.Context, repo *localrepo.Repo) <-chan cat return resultChan } -// catfileInfoFilter filters the catfileInfoResults from the provided channel with the filter +// CatfileInfoFilter filters the catfileInfoResults from the provided channel with the filter // function: if the filter returns `false` for a given item, then it will be dropped from the // pipeline. Errors cannot be filtered and will always be passed through. -func catfileInfoFilter(ctx context.Context, c <-chan catfileInfoResult, filter func(catfileInfoResult) bool) <-chan catfileInfoResult { - resultChan := make(chan catfileInfoResult) +func CatfileInfoFilter(ctx context.Context, c <-chan CatfileInfoResult, filter func(CatfileInfoResult) bool) <-chan CatfileInfoResult { + resultChan := make(chan CatfileInfoResult) go func() { defer close(resultChan) for result := range c { - if result.err != nil || filter(result) { + if result.Err != nil || filter(result) { select { case resultChan <- result: case <-ctx.Done(): @@ -323,18 +328,18 @@ func catfileInfoFilter(ctx context.Context, c <-chan catfileInfoResult, filter f return resultChan } -// catfileObjectResult is a result for the catfileObject pipeline step. -type catfileObjectResult struct { - // err is an error which occurred during execution of the pipeline. - err error +// CatfileObjectResult is a result for the CatfileObject pipeline step. +type CatfileObjectResult struct { + // Err is an error which occurred during execution of the pipeline. + Err error - // objectName is the object name as received from the revlistResultChan. - objectName []byte - // objectInfo is the object info of the object. - objectInfo *catfile.ObjectInfo + // ObjectName is the object name as received from the revlistResultChan. + ObjectName []byte + // ObjectInfo is the object info of the object. + ObjectInfo *catfile.ObjectInfo // obbjectReader is the reader for the raw object data. The reader must always be consumed // by the caller. - objectReader io.Reader + ObjectReader io.Reader } type signallingReader struct { @@ -353,21 +358,21 @@ func (r *signallingReader) Read(p []byte) (int, error) { return n, err } -// catfileObject processes catfileInfoResults from the given channel and reads associated objects +// CatfileObject processes catfileInfoResults from the given channel and reads associated objects // into memory via `git cat-file --batch`. The returned channel will contain all processed objects. // Any error received via the channel or encountered in this step will cause the pipeline to fail. // Context cancellation will gracefully halt the pipeline. The returned object readers must always // be fully consumed by the caller. -func catfileObject( +func CatfileObject( ctx context.Context, catfileProcess catfile.Batch, - catfileInfoResultChan <-chan catfileInfoResult, -) <-chan catfileObjectResult { - resultChan := make(chan catfileObjectResult) + catfileInfoResultChan <-chan CatfileInfoResult, +) <-chan CatfileObjectResult { + resultChan := make(chan CatfileObjectResult) go func() { defer close(resultChan) - sendResult := func(result catfileObjectResult) bool { + sendResult := func(result CatfileObjectResult) bool { select { case resultChan <- result: return false @@ -379,8 +384,8 @@ func catfileObject( var objectReader *signallingReader for catfileInfoResult := range catfileInfoResultChan { - if catfileInfoResult.err != nil { - sendResult(catfileObjectResult{err: catfileInfoResult.err}) + if catfileInfoResult.Err != nil { + sendResult(CatfileObjectResult{Err: catfileInfoResult.Err}) return } @@ -399,23 +404,23 @@ func catfileObject( var object *catfile.Object var err error - objectType := catfileInfoResult.objectInfo.Type + objectType := catfileInfoResult.ObjectInfo.Type switch objectType { case "tag": - object, err = catfileProcess.Tag(ctx, catfileInfoResult.objectInfo.Oid.Revision()) + object, err = catfileProcess.Tag(ctx, catfileInfoResult.ObjectInfo.Oid.Revision()) case "commit": - object, err = catfileProcess.Commit(ctx, catfileInfoResult.objectInfo.Oid.Revision()) + object, err = catfileProcess.Commit(ctx, catfileInfoResult.ObjectInfo.Oid.Revision()) case "tree": - object, err = catfileProcess.Tree(ctx, catfileInfoResult.objectInfo.Oid.Revision()) + object, err = catfileProcess.Tree(ctx, catfileInfoResult.ObjectInfo.Oid.Revision()) case "blob": - object, err = catfileProcess.Blob(ctx, catfileInfoResult.objectInfo.Oid.Revision()) + object, err = catfileProcess.Blob(ctx, catfileInfoResult.ObjectInfo.Oid.Revision()) default: err = fmt.Errorf("unknown object type %q", objectType) } if err != nil { - sendResult(catfileObjectResult{ - err: fmt.Errorf("requesting object: %w", err), + sendResult(CatfileObjectResult{ + Err: fmt.Errorf("requesting object: %w", err), }) return } @@ -425,10 +430,10 @@ func catfileObject( doneCh: make(chan interface{}), } - if isDone := sendResult(catfileObjectResult{ - objectName: catfileInfoResult.objectName, - objectInfo: catfileInfoResult.objectInfo, - objectReader: objectReader, + if isDone := sendResult(CatfileObjectResult{ + ObjectName: catfileInfoResult.ObjectName, + ObjectInfo: catfileInfoResult.ObjectInfo, + ObjectReader: objectReader, }); isDone { return } diff --git a/internal/gitaly/service/blob/pipeline_test.go b/internal/gitaly/service/blob/pipeline_test.go index 96c071d13..9aa38e69f 100644 --- a/internal/gitaly/service/blob/pipeline_test.go +++ b/internal/gitaly/service/blob/pipeline_test.go @@ -40,16 +40,16 @@ func TestRevlist(t *testing.T) { desc string precondition func(t *testing.T) revisions []string - options []revlistOption - expectedResults []revlistResult + options []RevlistOption + expectedResults []RevlistResult }{ { desc: "single blob", revisions: []string{ lfsPointer1, }, - expectedResults: []revlistResult{ - {oid: lfsPointer1}, + expectedResults: []RevlistResult{ + {OID: lfsPointer1}, }, }, { @@ -60,11 +60,11 @@ func TestRevlist(t *testing.T) { lfsPointer3, lfsPointer4, }, - expectedResults: []revlistResult{ - {oid: lfsPointer1}, - {oid: lfsPointer2}, - {oid: lfsPointer3}, - {oid: lfsPointer4}, + expectedResults: []RevlistResult{ + {OID: lfsPointer1}, + {OID: lfsPointer2}, + {OID: lfsPointer3}, + {OID: lfsPointer4}, }, }, { @@ -73,8 +73,8 @@ func TestRevlist(t *testing.T) { lfsPointer1, lfsPointer1, }, - expectedResults: []revlistResult{ - {oid: lfsPointer1}, + expectedResults: []RevlistResult{ + {OID: lfsPointer1}, }, }, { @@ -82,9 +82,9 @@ func TestRevlist(t *testing.T) { revisions: []string{ "b95c0fad32f4361845f91d9ce4c1721b52b82793", }, - expectedResults: []revlistResult{ - {oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, - {oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", objectName: []byte("branch-test.txt")}, + expectedResults: []RevlistResult{ + {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, + {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")}, }, }, { @@ -93,14 +93,14 @@ func TestRevlist(t *testing.T) { "^refs/heads/master~", "refs/heads/master", }, - expectedResults: []revlistResult{ - {oid: "1e292f8fedd741b75372e19097c76d327140c312"}, - {oid: "07f8147e8e73aab6c935c296e8cdc5194dee729b"}, - {oid: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", objectName: []byte("files")}, - {oid: "2132d150328bd9334cc4e62a16a5d998a7e399b9", objectName: []byte("files/flat")}, - {oid: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", objectName: []byte("files/flat/path")}, - {oid: "ea7249055466085d0a6c69951908ef47757e92f4", objectName: []byte("files/flat/path/correct")}, - {oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + expectedResults: []RevlistResult{ + {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, + {OID: "07f8147e8e73aab6c935c296e8cdc5194dee729b"}, + {OID: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", ObjectName: []byte("files")}, + {OID: "2132d150328bd9334cc4e62a16a5d998a7e399b9", ObjectName: []byte("files/flat")}, + {OID: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", ObjectName: []byte("files/flat/path")}, + {OID: "ea7249055466085d0a6c69951908ef47757e92f4", ObjectName: []byte("files/flat/path/correct")}, + {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, }, }, { @@ -114,17 +114,17 @@ func TestRevlist(t *testing.T) { revisions: []string{ "79d5f98270ad677c86a7e1ab2baa922958565135", }, - expectedResults: []revlistResult{ - {oid: "79d5f98270ad677c86a7e1ab2baa922958565135"}, - {oid: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", objectName: []byte("feature-1.txt")}, - {oid: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", objectName: []byte("feature-2.txt")}, - {oid: "0fb47f093f769008049a0b0976ac3fa6d6125033", objectName: []byte("hotfix-1.txt")}, - {oid: "4ae6c5e14452a35d04156277ae63e8356eb17cae", objectName: []byte("hotfix-2.txt")}, - {oid: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", objectName: []byte("iso8859.txt")}, - {oid: "570f8e1dfe8149c1d17002712310d43dfeb43159", objectName: []byte("russian.rb")}, - {oid: "7a17968582c21c9153ec24c6a9d5f33592ad9103", objectName: []byte("test.txt")}, - {oid: "f3064a3aa9c14277483f690250072e987e2c8356", objectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, - {oid: "3a26c18b02e843b459732e7ade7ab9a154a1002b", objectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, + expectedResults: []RevlistResult{ + {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, + {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")}, + {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")}, + {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, + {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, + {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")}, + {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")}, + {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, + {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, }, }, { @@ -134,14 +134,14 @@ func TestRevlist(t *testing.T) { revisions: []string{ "79d5f98270ad677c86a7e1ab2baa922958565135", }, - options: []revlistOption{ - withBlobLimit(10), + options: []RevlistOption{ + WithBlobLimit(10), }, - expectedResults: []revlistResult{ - {oid: "79d5f98270ad677c86a7e1ab2baa922958565135"}, - {oid: "0fb47f093f769008049a0b0976ac3fa6d6125033", objectName: []byte("hotfix-1.txt")}, - {oid: "4ae6c5e14452a35d04156277ae63e8356eb17cae", objectName: []byte("hotfix-2.txt")}, - {oid: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", objectName: []byte("iso8859.txt")}, + expectedResults: []RevlistResult{ + {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, + {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, + {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, + {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, }, }, { @@ -150,19 +150,19 @@ func TestRevlist(t *testing.T) { revisions: []string{ "79d5f98270ad677c86a7e1ab2baa922958565135", }, - options: []revlistOption{ - withObjectTypeFilter(objectTypeBlob), + options: []RevlistOption{ + WithObjectTypeFilter(ObjectTypeBlob), }, - expectedResults: []revlistResult{ - {oid: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", objectName: []byte("feature-1.txt")}, - {oid: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", objectName: []byte("feature-2.txt")}, - {oid: "0fb47f093f769008049a0b0976ac3fa6d6125033", objectName: []byte("hotfix-1.txt")}, - {oid: "4ae6c5e14452a35d04156277ae63e8356eb17cae", objectName: []byte("hotfix-2.txt")}, - {oid: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", objectName: []byte("iso8859.txt")}, - {oid: "570f8e1dfe8149c1d17002712310d43dfeb43159", objectName: []byte("russian.rb")}, - {oid: "7a17968582c21c9153ec24c6a9d5f33592ad9103", objectName: []byte("test.txt")}, - {oid: "f3064a3aa9c14277483f690250072e987e2c8356", objectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, - {oid: "3a26c18b02e843b459732e7ade7ab9a154a1002b", objectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, + expectedResults: []RevlistResult{ + {OID: "8af7f880ce38649fc49f66e3f38857bfbec3f0b7", ObjectName: []byte("feature-1.txt")}, + {OID: "16ca0b267f82cd2f5ca1157dd162dae98745eab8", ObjectName: []byte("feature-2.txt")}, + {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, + {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, + {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, + {OID: "570f8e1dfe8149c1d17002712310d43dfeb43159", ObjectName: []byte("russian.rb")}, + {OID: "7a17968582c21c9153ec24c6a9d5f33592ad9103", ObjectName: []byte("test.txt")}, + {OID: "f3064a3aa9c14277483f690250072e987e2c8356", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.txt")}, + {OID: "3a26c18b02e843b459732e7ade7ab9a154a1002b", ObjectName: []byte("\xe3\x83\x86\xe3\x82\xb9\xe3\x83\x88.xls")}, }, }, { @@ -171,13 +171,13 @@ func TestRevlist(t *testing.T) { revisions: []string{ "--all", }, - options: []revlistOption{ - withObjectTypeFilter(objectTypeTag), + options: []RevlistOption{ + WithObjectTypeFilter(ObjectTypeTag), }, - expectedResults: []revlistResult{ - {oid: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", objectName: []byte("v1.0.0")}, - {oid: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", objectName: []byte("v1.1.0")}, - {oid: "8f03acbcd11c53d9c9468078f32a2622005a4841", objectName: []byte("v1.1.1")}, + expectedResults: []RevlistResult{ + {OID: "f4e6814c3e4e7a0de82a9e7cd20c626cc963a2f8", ObjectName: []byte("v1.0.0")}, + {OID: "8a2a6eb295bb170b34c24c76c49ed0e9b2eaf34b", ObjectName: []byte("v1.1.0")}, + {OID: "8f03acbcd11c53d9c9468078f32a2622005a4841", ObjectName: []byte("v1.1.1")}, }, }, { @@ -186,11 +186,11 @@ func TestRevlist(t *testing.T) { revisions: []string{ "79d5f98270ad677c86a7e1ab2baa922958565135", }, - options: []revlistOption{ - withObjectTypeFilter(objectTypeTree), + options: []RevlistOption{ + WithObjectTypeFilter(ObjectTypeTree), }, - expectedResults: []revlistResult{ - {oid: "79d5f98270ad677c86a7e1ab2baa922958565135"}, + expectedResults: []RevlistResult{ + {OID: "79d5f98270ad677c86a7e1ab2baa922958565135"}, }, }, { @@ -200,12 +200,12 @@ func TestRevlist(t *testing.T) { "^refs/heads/master~", "refs/heads/master", }, - options: []revlistOption{ - withObjectTypeFilter(objectTypeCommit), + options: []RevlistOption{ + WithObjectTypeFilter(ObjectTypeCommit), }, - expectedResults: []revlistResult{ - {oid: "1e292f8fedd741b75372e19097c76d327140c312"}, - {oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, + expectedResults: []RevlistResult{ + {OID: "1e292f8fedd741b75372e19097c76d327140c312"}, + {OID: "c1c67abbaf91f624347bb3ae96eabe3a1b742478"}, }, }, { @@ -214,14 +214,14 @@ func TestRevlist(t *testing.T) { revisions: []string{ "79d5f98270ad677c86a7e1ab2baa922958565135", }, - options: []revlistOption{ - withBlobLimit(10), - withObjectTypeFilter(objectTypeBlob), + options: []RevlistOption{ + WithBlobLimit(10), + WithObjectTypeFilter(ObjectTypeBlob), }, - expectedResults: []revlistResult{ - {oid: "0fb47f093f769008049a0b0976ac3fa6d6125033", objectName: []byte("hotfix-1.txt")}, - {oid: "4ae6c5e14452a35d04156277ae63e8356eb17cae", objectName: []byte("hotfix-2.txt")}, - {oid: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", objectName: []byte("iso8859.txt")}, + expectedResults: []RevlistResult{ + {OID: "0fb47f093f769008049a0b0976ac3fa6d6125033", ObjectName: []byte("hotfix-1.txt")}, + {OID: "4ae6c5e14452a35d04156277ae63e8356eb17cae", ObjectName: []byte("hotfix-2.txt")}, + {OID: "b988ffed90cb6a9b7f98a3686a933edb3c5d70c0", ObjectName: []byte("iso8859.txt")}, }, }, { @@ -229,8 +229,8 @@ func TestRevlist(t *testing.T) { revisions: []string{ "refs/heads/does-not-exist", }, - expectedResults: []revlistResult{ - {err: errors.New("rev-list pipeline command: exit status 128")}, + expectedResults: []RevlistResult{ + {Err: errors.New("rev-list pipeline command: exit status 128")}, }, }, { @@ -239,8 +239,8 @@ func TestRevlist(t *testing.T) { lfsPointer1, "refs/heads/does-not-exist", }, - expectedResults: []revlistResult{ - {err: errors.New("rev-list pipeline command: exit status 128")}, + expectedResults: []RevlistResult{ + {Err: errors.New("rev-list pipeline command: exit status 128")}, }, }, } { @@ -252,14 +252,14 @@ func TestRevlist(t *testing.T) { ctx, cancel := testhelper.Context() defer cancel() - resultChan := revlist(ctx, repo, tc.revisions, tc.options...) + resultChan := Revlist(ctx, repo, tc.revisions, tc.options...) - var results []revlistResult + var results []RevlistResult for result := range resultChan { // We're converting the error here to a plain un-nested error such // that we don't have to replicate the complete error's structure. - if result.err != nil { - result.err = errors.New(result.err.Error()) + if result.Err != nil { + result.Err = errors.New(result.Err.Error()) } results = append(results, result) @@ -273,65 +273,65 @@ func TestRevlist(t *testing.T) { func TestRevlistFilter(t *testing.T) { for _, tc := range []struct { desc string - input []revlistResult - filter func(revlistResult) bool - expectedResults []revlistResult + input []RevlistResult + filter func(RevlistResult) bool + expectedResults []RevlistResult }{ { desc: "all accepted", - input: []revlistResult{ - {oid: "a"}, - {oid: "b"}, - {oid: "c"}, + input: []RevlistResult{ + {OID: "a"}, + {OID: "b"}, + {OID: "c"}, }, - filter: func(revlistResult) bool { + filter: func(RevlistResult) bool { return true }, - expectedResults: []revlistResult{ - {oid: "a"}, - {oid: "b"}, - {oid: "c"}, + expectedResults: []RevlistResult{ + {OID: "a"}, + {OID: "b"}, + {OID: "c"}, }, }, { desc: "all filtered", - input: []revlistResult{ - {oid: "a"}, - {oid: "b"}, - {oid: "c"}, + input: []RevlistResult{ + {OID: "a"}, + {OID: "b"}, + {OID: "c"}, }, - filter: func(revlistResult) bool { + filter: func(RevlistResult) bool { return false }, expectedResults: nil, }, { desc: "errors always get through", - input: []revlistResult{ - {oid: "a"}, - {oid: "b"}, - {err: errors.New("foobar")}, - {oid: "c"}, + input: []RevlistResult{ + {OID: "a"}, + {OID: "b"}, + {Err: errors.New("foobar")}, + {OID: "c"}, }, - filter: func(revlistResult) bool { + filter: func(RevlistResult) bool { return false }, - expectedResults: []revlistResult{ - {err: errors.New("foobar")}, + expectedResults: []RevlistResult{ + {Err: errors.New("foobar")}, }, }, { desc: "subset filtered", - input: []revlistResult{ - {oid: "a"}, - {oid: "b"}, - {oid: "c"}, + input: []RevlistResult{ + {OID: "a"}, + {OID: "b"}, + {OID: "c"}, }, - filter: func(r revlistResult) bool { - return r.oid == "b" + filter: func(r RevlistResult) bool { + return r.OID == "b" }, - expectedResults: []revlistResult{ - {oid: "b"}, + expectedResults: []RevlistResult{ + {OID: "b"}, }, }, } { @@ -339,14 +339,14 @@ func TestRevlistFilter(t *testing.T) { ctx, cancel := testhelper.Context() defer cancel() - inputChan := make(chan revlistResult, len(tc.input)) + inputChan := make(chan RevlistResult, len(tc.input)) for _, input := range tc.input { inputChan <- input } close(inputChan) - var results []revlistResult - for result := range revlistFilter(ctx, inputChan, tc.filter) { + var results []RevlistResult + for result := range RevlistFilter(ctx, inputChan, tc.filter) { results = append(results, result) } @@ -364,63 +364,63 @@ func TestCatfileInfo(t *testing.T) { for _, tc := range []struct { desc string - revlistInputs []revlistResult - expectedResults []catfileInfoResult + revlistInputs []RevlistResult + expectedResults []CatfileInfoResult }{ { desc: "single blob", - revlistInputs: []revlistResult{ - {oid: lfsPointer1}, + revlistInputs: []RevlistResult{ + {OID: lfsPointer1}, }, - expectedResults: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, }, }, { desc: "multiple blobs", - revlistInputs: []revlistResult{ - {oid: lfsPointer1}, - {oid: lfsPointer2}, - {oid: lfsPointer3}, - {oid: lfsPointer4}, + revlistInputs: []RevlistResult{ + {OID: lfsPointer1}, + {OID: lfsPointer2}, + {OID: lfsPointer3}, + {OID: lfsPointer4}, }, - expectedResults: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, }, }, { desc: "object name", - revlistInputs: []revlistResult{ - {oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, - {oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", objectName: []byte("branch-test.txt")}, + revlistInputs: []RevlistResult{ + {OID: "b95c0fad32f4361845f91d9ce4c1721b52b82793"}, + {OID: "93e123ac8a3e6a0b600953d7598af629dec7b735", ObjectName: []byte("branch-test.txt")}, }, - expectedResults: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {objectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, objectName: []byte("branch-test.txt")}, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, }, }, { desc: "invalid object ID", - revlistInputs: []revlistResult{ - {oid: "invalidobjectid"}, + revlistInputs: []RevlistResult{ + {OID: "invalidobjectid"}, }, - expectedResults: []catfileInfoResult{ - {err: errors.New("retrieving object info for \"invalidobjectid\": object not found")}, + expectedResults: []CatfileInfoResult{ + {Err: errors.New("retrieving object info for \"invalidobjectid\": object not found")}, }, }, { desc: "mixed valid and invalid revision", - revlistInputs: []revlistResult{ - {oid: lfsPointer1}, - {oid: "invalidobjectid"}, - {oid: lfsPointer2}, + revlistInputs: []RevlistResult{ + {OID: lfsPointer1}, + {OID: "invalidobjectid"}, + {OID: lfsPointer2}, }, - expectedResults: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {err: errors.New("retrieving object info for \"invalidobjectid\": object not found")}, + expectedResults: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {Err: errors.New("retrieving object info for \"invalidobjectid\": object not found")}, }, }, } { @@ -434,20 +434,20 @@ func TestCatfileInfo(t *testing.T) { catfileProcess, err := catfileCache.BatchProcess(ctx, repo) require.NoError(t, err) - revlistResultChan := make(chan revlistResult, len(tc.revlistInputs)) + revlistResultChan := make(chan RevlistResult, len(tc.revlistInputs)) for _, input := range tc.revlistInputs { revlistResultChan <- input } close(revlistResultChan) - resultChan := catfileInfo(ctx, catfileProcess, revlistResultChan) + resultChan := CatfileInfo(ctx, catfileProcess, revlistResultChan) - var results []catfileInfoResult + var results []CatfileInfoResult for result := range resultChan { // We're converting the error here to a plain un-nested error such // that we don't have to replicate the complete error's structure. - if result.err != nil { - result.err = errors.New(result.err.Error()) + if result.Err != nil { + result.Err = errors.New(result.Err.Error()) } results = append(results, result) @@ -475,83 +475,83 @@ func TestCatfileAllObjects(t *testing.T) { }) commit := gittest.WriteCommit(t, cfg, repoPath, gittest.WithParents()) - resultChan := catfileInfoAllObjects(ctx, repo) + resultChan := CatfileInfoAllObjects(ctx, repo) - var results []catfileInfoResult + var results []CatfileInfoResult for result := range resultChan { - require.NoError(t, result.err) + require.NoError(t, result.Err) results = append(results, result) } - require.ElementsMatch(t, []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: blob1, Type: "blob", Size: 6}}, - {objectInfo: &catfile.ObjectInfo{Oid: blob2, Type: "blob", Size: 6}}, - {objectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: 34}}, - {objectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: 177}}, + require.ElementsMatch(t, []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: blob1, Type: "blob", Size: 6}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: blob2, Type: "blob", Size: 6}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: tree, Type: "tree", Size: 34}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: commit, Type: "commit", Size: 177}}, }, results) } func TestCatfileInfoFilter(t *testing.T) { for _, tc := range []struct { desc string - input []catfileInfoResult - filter func(catfileInfoResult) bool - expectedResults []catfileInfoResult + input []CatfileInfoResult + filter func(CatfileInfoResult) bool + expectedResults []CatfileInfoResult }{ { desc: "all accepted", - input: []catfileInfoResult{ - {objectName: []byte{'a'}}, - {objectName: []byte{'b'}}, - {objectName: []byte{'c'}}, + input: []CatfileInfoResult{ + {ObjectName: []byte{'a'}}, + {ObjectName: []byte{'b'}}, + {ObjectName: []byte{'c'}}, }, - filter: func(catfileInfoResult) bool { + filter: func(CatfileInfoResult) bool { return true }, - expectedResults: []catfileInfoResult{ - {objectName: []byte{'a'}}, - {objectName: []byte{'b'}}, - {objectName: []byte{'c'}}, + expectedResults: []CatfileInfoResult{ + {ObjectName: []byte{'a'}}, + {ObjectName: []byte{'b'}}, + {ObjectName: []byte{'c'}}, }, }, { desc: "all filtered", - input: []catfileInfoResult{ - {objectName: []byte{'a'}}, - {objectName: []byte{'b'}}, - {objectName: []byte{'c'}}, + input: []CatfileInfoResult{ + {ObjectName: []byte{'a'}}, + {ObjectName: []byte{'b'}}, + {ObjectName: []byte{'c'}}, }, - filter: func(catfileInfoResult) bool { + filter: func(CatfileInfoResult) bool { return false }, }, { desc: "errors always get through", - input: []catfileInfoResult{ - {objectName: []byte{'a'}}, - {objectName: []byte{'b'}}, - {err: errors.New("foobar")}, - {objectName: []byte{'c'}}, + input: []CatfileInfoResult{ + {ObjectName: []byte{'a'}}, + {ObjectName: []byte{'b'}}, + {Err: errors.New("foobar")}, + {ObjectName: []byte{'c'}}, }, - filter: func(catfileInfoResult) bool { + filter: func(CatfileInfoResult) bool { return false }, - expectedResults: []catfileInfoResult{ - {err: errors.New("foobar")}, + expectedResults: []CatfileInfoResult{ + {Err: errors.New("foobar")}, }, }, { desc: "subset filtered", - input: []catfileInfoResult{ - {objectName: []byte{'a'}}, - {objectName: []byte{'b'}}, - {objectName: []byte{'c'}}, + input: []CatfileInfoResult{ + {ObjectName: []byte{'a'}}, + {ObjectName: []byte{'b'}}, + {ObjectName: []byte{'c'}}, }, - filter: func(r catfileInfoResult) bool { - return r.objectName[0] == 'b' + filter: func(r CatfileInfoResult) bool { + return r.ObjectName[0] == 'b' }, - expectedResults: []catfileInfoResult{ - {objectName: []byte{'b'}}, + expectedResults: []CatfileInfoResult{ + {ObjectName: []byte{'b'}}, }, }, } { @@ -559,14 +559,14 @@ func TestCatfileInfoFilter(t *testing.T) { ctx, cancel := testhelper.Context() defer cancel() - inputChan := make(chan catfileInfoResult, len(tc.input)) + inputChan := make(chan CatfileInfoResult, len(tc.input)) for _, input := range tc.input { inputChan <- input } close(inputChan) - var results []catfileInfoResult - for result := range catfileInfoFilter(ctx, inputChan, tc.filter) { + var results []CatfileInfoResult + for result := range CatfileInfoFilter(ctx, inputChan, tc.filter) { results = append(results, result) } @@ -584,72 +584,72 @@ func TestCatfileObject(t *testing.T) { for _, tc := range []struct { desc string - catfileInfoInputs []catfileInfoResult - expectedResults []catfileObjectResult + catfileInfoInputs []CatfileInfoResult + expectedResults []CatfileObjectResult }{ { desc: "single blob", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, }, }, { desc: "multiple blobs", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer4, Type: "blob", Size: 129}}, }, }, { desc: "revlist result with object names", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {objectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, objectName: []byte("branch-test.txt")}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {objectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, objectName: []byte("branch-test.txt")}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, }, }, { desc: "invalid object ID", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "invalidobjectid", Type: "blob"}}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "invalidobjectid", Type: "blob"}}, }, - expectedResults: []catfileObjectResult{ - {err: errors.New("requesting object: object not found")}, + expectedResults: []CatfileObjectResult{ + {Err: errors.New("requesting object: object not found")}, }, }, { desc: "invalid object type", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "foobar"}}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "foobar"}}, }, - expectedResults: []catfileObjectResult{ - {err: errors.New("requesting object: unknown object type \"foobar\"")}, + expectedResults: []CatfileObjectResult{ + {Err: errors.New("requesting object: unknown object type \"foobar\"")}, }, }, { desc: "mixed valid and invalid revision", - catfileInfoInputs: []catfileInfoResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "foobar"}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2}}, + catfileInfoInputs: []CatfileInfoResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "foobar"}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2}}, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {err: errors.New("requesting object: unknown object type \"foobar\"")}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {Err: errors.New("requesting object: unknown object type \"foobar\"")}, }, }, } { @@ -663,32 +663,32 @@ func TestCatfileObject(t *testing.T) { catfileProcess, err := catfileCache.BatchProcess(ctx, repo) require.NoError(t, err) - catfileInfoResultChan := make(chan catfileInfoResult, len(tc.catfileInfoInputs)) + catfileInfoResultChan := make(chan CatfileInfoResult, len(tc.catfileInfoInputs)) for _, input := range tc.catfileInfoInputs { catfileInfoResultChan <- input } close(catfileInfoResultChan) - resultChan := catfileObject(ctx, catfileProcess, catfileInfoResultChan) + resultChan := CatfileObject(ctx, catfileProcess, catfileInfoResultChan) - var results []catfileObjectResult + var results []CatfileObjectResult for result := range resultChan { // We're converting the error here to a plain un-nested error such // that we don't have to replicate the complete error's structure. - if result.err != nil { - result.err = errors.New(result.err.Error()) + if result.Err != nil { + result.Err = errors.New(result.Err.Error()) } - if result.err == nil { + if result.Err == nil { // While we could also assert object data, let's not do // this: it would just be too annoying. - require.NotNil(t, result.objectReader) + require.NotNil(t, result.ObjectReader) - objectData, err := ioutil.ReadAll(result.objectReader) + objectData, err := ioutil.ReadAll(result.ObjectReader) require.NoError(t, err) - require.Len(t, objectData, int(result.objectInfo.Size)) + require.Len(t, objectData, int(result.ObjectInfo.Size)) - result.objectReader = nil + result.ObjectReader = nil } results = append(results, result) @@ -709,17 +709,17 @@ func TestPipeline(t *testing.T) { for _, tc := range []struct { desc string revisions []string - revlistFilter func(revlistResult) bool - catfileInfoFilter func(catfileInfoResult) bool - expectedResults []catfileObjectResult + revlistFilter func(RevlistResult) bool + catfileInfoFilter func(CatfileInfoResult) bool + expectedResults []CatfileObjectResult }{ { desc: "single blob", revisions: []string{ lfsPointer1, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, }, }, { @@ -729,10 +729,10 @@ func TestPipeline(t *testing.T) { lfsPointer2, lfsPointer3, }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer3, Type: "blob", Size: 127}}, }, }, { @@ -742,11 +742,11 @@ func TestPipeline(t *testing.T) { lfsPointer2, lfsPointer3, }, - revlistFilter: func(r revlistResult) bool { - return r.oid == lfsPointer2 + revlistFilter: func(r RevlistResult) bool { + return r.OID == lfsPointer2 }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}}, }, }, { @@ -754,9 +754,9 @@ func TestPipeline(t *testing.T) { revisions: []string{ "b95c0fad32f4361845f91d9ce4c1721b52b82793", }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, - {objectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, objectName: []byte("branch-test.txt")}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "b95c0fad32f4361845f91d9ce4c1721b52b82793", Type: "tree", Size: 43}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, }, }, { @@ -764,11 +764,11 @@ func TestPipeline(t *testing.T) { revisions: []string{ "b95c0fad32f4361845f91d9ce4c1721b52b82793", }, - catfileInfoFilter: func(r catfileInfoResult) bool { - return r.objectInfo.Type == "blob" + catfileInfoFilter: func(r CatfileInfoResult) bool { + return r.ObjectInfo.Type == "blob" }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, objectName: []byte("branch-test.txt")}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "93e123ac8a3e6a0b600953d7598af629dec7b735", Type: "blob", Size: 59}, ObjectName: []byte("branch-test.txt")}, }, }, { @@ -777,14 +777,14 @@ func TestPipeline(t *testing.T) { "^master~", "master", }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}, - {objectInfo: &catfile.ObjectInfo{Oid: "07f8147e8e73aab6c935c296e8cdc5194dee729b", Type: "tree", Size: 780}}, - {objectInfo: &catfile.ObjectInfo{Oid: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", Type: "tree", Size: 258}, objectName: []byte("files")}, - {objectInfo: &catfile.ObjectInfo{Oid: "2132d150328bd9334cc4e62a16a5d998a7e399b9", Type: "tree", Size: 31}, objectName: []byte("files/flat")}, - {objectInfo: &catfile.ObjectInfo{Oid: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", Type: "tree", Size: 34}, objectName: []byte("files/flat/path")}, - {objectInfo: &catfile.ObjectInfo{Oid: "ea7249055466085d0a6c69951908ef47757e92f4", Type: "tree", Size: 39}, objectName: []byte("files/flat/path/correct")}, - {objectInfo: &catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: "1e292f8fedd741b75372e19097c76d327140c312", Type: "commit", Size: 388}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "07f8147e8e73aab6c935c296e8cdc5194dee729b", Type: "tree", Size: 780}}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "ceb102b8d3f9a95c2eb979213e49f7cc1b23d56e", Type: "tree", Size: 258}, ObjectName: []byte("files")}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "2132d150328bd9334cc4e62a16a5d998a7e399b9", Type: "tree", Size: 31}, ObjectName: []byte("files/flat")}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "f3942dc8b824a2c9359e518d48e68f84461bd2f7", Type: "tree", Size: 34}, ObjectName: []byte("files/flat/path")}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "ea7249055466085d0a6c69951908ef47757e92f4", Type: "tree", Size: 39}, ObjectName: []byte("files/flat/path/correct")}, + {ObjectInfo: &catfile.ObjectInfo{Oid: "c1c67abbaf91f624347bb3ae96eabe3a1b742478", Type: "commit", Size: 326}}, }, }, { @@ -792,18 +792,18 @@ func TestPipeline(t *testing.T) { revisions: []string{ "--all", }, - revlistFilter: func(r revlistResult) bool { + revlistFilter: func(r RevlistResult) bool { // Let through two LFS pointers and a tree. - return r.oid == "b95c0fad32f4361845f91d9ce4c1721b52b82793" || - r.oid == lfsPointer1 || r.oid == lfsPointer2 + return r.OID == "b95c0fad32f4361845f91d9ce4c1721b52b82793" || + r.OID == lfsPointer1 || r.OID == lfsPointer2 }, - catfileInfoFilter: func(r catfileInfoResult) bool { + catfileInfoFilter: func(r CatfileInfoResult) bool { // Only let through blobs, so only the two LFS pointers remain. - return r.objectInfo.Type == "blob" + return r.ObjectInfo.Type == "blob" }, - expectedResults: []catfileObjectResult{ - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}, objectName: []byte("files/lfs/lfs_object.iso")}, - {objectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}, objectName: []byte("another.lfs")}, + expectedResults: []CatfileObjectResult{ + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer1, Type: "blob", Size: 133}, ObjectName: []byte("files/lfs/lfs_object.iso")}, + {ObjectInfo: &catfile.ObjectInfo{Oid: lfsPointer2, Type: "blob", Size: 127}, ObjectName: []byte("another.lfs")}, }, }, { @@ -811,8 +811,8 @@ func TestPipeline(t *testing.T) { revisions: []string{ "doesnotexist", }, - expectedResults: []catfileObjectResult{ - {err: errors.New("rev-list pipeline command: exit status 128")}, + expectedResults: []CatfileObjectResult{ + {Err: errors.New("rev-list pipeline command: exit status 128")}, }, }, { @@ -822,8 +822,8 @@ func TestPipeline(t *testing.T) { "doesnotexist", lfsPointer2, }, - expectedResults: []catfileObjectResult{ - {err: errors.New("rev-list pipeline command: exit status 128")}, + expectedResults: []CatfileObjectResult{ + {Err: errors.New("rev-list pipeline command: exit status 128")}, }, }, { @@ -831,16 +831,16 @@ func TestPipeline(t *testing.T) { revisions: []string{ "doesnotexist", }, - revlistFilter: func(r revlistResult) bool { + revlistFilter: func(r RevlistResult) bool { require.Fail(t, "filter should not be invoked on errors") return true }, - catfileInfoFilter: func(r catfileInfoResult) bool { + catfileInfoFilter: func(r CatfileInfoResult) bool { require.Fail(t, "filter should not be invoked on errors") return true }, - expectedResults: []catfileObjectResult{ - {err: errors.New("rev-list pipeline command: exit status 128")}, + expectedResults: []CatfileObjectResult{ + {Err: errors.New("rev-list pipeline command: exit status 128")}, }, }, } { @@ -854,36 +854,36 @@ func TestPipeline(t *testing.T) { catfileProcess, err := catfileCache.BatchProcess(ctx, repo) require.NoError(t, err) - revlistChan := revlist(ctx, repo, tc.revisions) + revlistChan := Revlist(ctx, repo, tc.revisions) if tc.revlistFilter != nil { - revlistChan = revlistFilter(ctx, revlistChan, tc.revlistFilter) + revlistChan = RevlistFilter(ctx, revlistChan, tc.revlistFilter) } - catfileInfoChan := catfileInfo(ctx, catfileProcess, revlistChan) + catfileInfoChan := CatfileInfo(ctx, catfileProcess, revlistChan) if tc.catfileInfoFilter != nil { - catfileInfoChan = catfileInfoFilter(ctx, catfileInfoChan, tc.catfileInfoFilter) + catfileInfoChan = CatfileInfoFilter(ctx, catfileInfoChan, tc.catfileInfoFilter) } - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) - var results []catfileObjectResult + var results []CatfileObjectResult for result := range catfileObjectChan { // We're converting the error here to a plain un-nested error such // that we don't have to replicate the complete error's structure. - if result.err != nil { - result.err = errors.New(result.err.Error()) + if result.Err != nil { + result.Err = errors.New(result.Err.Error()) } - if result.err == nil { + if result.Err == nil { // While we could also assert object data, let's not do // this: it would just be too annoying. - require.NotNil(t, result.objectReader) + require.NotNil(t, result.ObjectReader) - objectData, err := ioutil.ReadAll(result.objectReader) + objectData, err := ioutil.ReadAll(result.ObjectReader) require.NoError(t, err) - require.Len(t, objectData, int(result.objectInfo.Size)) + require.Len(t, objectData, int(result.ObjectInfo.Size)) - result.objectReader = nil + result.ObjectReader = nil } results = append(results, result) @@ -908,18 +908,18 @@ func TestPipeline(t *testing.T) { childCtx, cancel := context.WithCancel(ctx) defer cancel() - revlistChan := revlist(childCtx, repo, []string{"--all"}) - revlistChan = revlistFilter(childCtx, revlistChan, func(revlistResult) bool { return true }) - catfileInfoChan := catfileInfo(childCtx, catfileProcess, revlistChan) - catfileInfoChan = catfileInfoFilter(childCtx, catfileInfoChan, func(catfileInfoResult) bool { return true }) - catfileObjectChan := catfileObject(childCtx, catfileProcess, catfileInfoChan) + revlistChan := Revlist(childCtx, repo, []string{"--all"}) + revlistChan = RevlistFilter(childCtx, revlistChan, func(RevlistResult) bool { return true }) + catfileInfoChan := CatfileInfo(childCtx, catfileProcess, revlistChan) + catfileInfoChan = CatfileInfoFilter(childCtx, catfileInfoChan, func(CatfileInfoResult) bool { return true }) + catfileObjectChan := CatfileObject(childCtx, catfileProcess, catfileInfoChan) i := 0 for result := range catfileObjectChan { - require.NoError(t, result.err) + require.NoError(t, result.Err) i++ - _, err := io.Copy(ioutil.Discard, result.objectReader) + _, err := io.Copy(ioutil.Discard, result.ObjectReader) require.NoError(t, err) if i == 3 { @@ -943,14 +943,14 @@ func TestPipeline(t *testing.T) { catfileProcess, err := catfileCache.BatchProcess(ctx, repo) require.NoError(t, err) - revlistChan := revlist(ctx, repo, []string{"--all"}) - catfileInfoChan := catfileInfo(ctx, catfileProcess, revlistChan) - catfileObjectChan := catfileObject(ctx, catfileProcess, catfileInfoChan) + revlistChan := Revlist(ctx, repo, []string{"--all"}) + catfileInfoChan := CatfileInfo(ctx, catfileProcess, revlistChan) + catfileObjectChan := CatfileObject(ctx, catfileProcess, catfileInfoChan) i := 0 var wg sync.WaitGroup for result := range catfileObjectChan { - require.NoError(t, result.err) + require.NoError(t, result.Err) wg.Add(1) i++ @@ -961,9 +961,9 @@ func TestPipeline(t *testing.T) { // until we've read the old object. Chances are high though that we'd // eventually hit the race here in case we didn't correctly synchronize on // the object reader. - go func(object catfileObjectResult) { + go func(object CatfileObjectResult) { defer wg.Done() - _, err := io.Copy(ioutil.Discard, object.objectReader) + _, err := io.Copy(ioutil.Discard, object.ObjectReader) require.NoError(t, err) }(result) } |