diff options
author | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-10-13 15:54:32 +0300 |
---|---|---|
committer | Patrick Steinhardt <psteinhardt@gitlab.com> | 2021-10-20 09:10:42 +0300 |
commit | 7325a99d7b01f8645369402b5e5fdf5c9adc4241 (patch) | |
tree | 112f79aeff406ef1989a330d501d44b5c30fa473 | |
parent | 4ee94b7552c87bab24244c76ce9e6a858b56772c (diff) |
gitpipe: Allow using iterators interchangeably as input
The pipeline architecture in the gitpipe package is currently quite
strict given that we cannot use e.g. the `Revlist()` iterator as input
to the `CatfileObject()` step. It's thus hard to mix-and-match pipeline
steps.
Lift this limitation by introducing a new ObjectIterator interface which
is common to all iterators: all it provides is access to the object ID
and name. It's thus sufficient to be used as input iterator for all of
the pipeline steps which do accept an input iterator.
-rw-r--r-- | internal/git/gitpipe/catfile_info.go | 14 | ||||
-rw-r--r-- | internal/git/gitpipe/catfile_info_iterator.go | 15 | ||||
-rw-r--r-- | internal/git/gitpipe/catfile_object.go | 10 | ||||
-rw-r--r-- | internal/git/gitpipe/catfile_object_iterator.go | 15 | ||||
-rw-r--r-- | internal/git/gitpipe/object_iterator.go | 19 | ||||
-rw-r--r-- | internal/git/gitpipe/revision_iterator.go | 15 |
6 files changed, 62 insertions, 26 deletions
diff --git a/internal/git/gitpipe/catfile_info.go b/internal/git/gitpipe/catfile_info.go index fe3104017..337760810 100644 --- a/internal/git/gitpipe/catfile_info.go +++ b/internal/git/gitpipe/catfile_info.go @@ -47,7 +47,7 @@ func WithSkipCatfileInfoResult(skipResult func(*catfile.ObjectInfo) bool) Catfil func CatfileInfo( ctx context.Context, objectInfoReader catfile.ObjectInfoReader, - revisionIterator RevisionIterator, + it ObjectIterator, opts ...CatfileInfoOption, ) CatfileInfoIterator { var cfg catfileInfoConfig @@ -59,13 +59,11 @@ func CatfileInfo( go func() { defer close(resultChan) - for revisionIterator.Next() { - revlistResult := revisionIterator.Result() - - objectInfo, err := objectInfoReader.Info(ctx, revlistResult.OID.Revision()) + for it.Next() { + objectInfo, err := objectInfoReader.Info(ctx, it.ObjectID().Revision()) if err != nil { sendCatfileInfoResult(ctx, resultChan, CatfileInfoResult{ - err: fmt.Errorf("retrieving object info for %q: %w", revlistResult.OID, err), + err: fmt.Errorf("retrieving object info for %q: %w", it.ObjectID(), err), }) return } @@ -75,14 +73,14 @@ func CatfileInfo( } if isDone := sendCatfileInfoResult(ctx, resultChan, CatfileInfoResult{ - ObjectName: revlistResult.ObjectName, + ObjectName: it.ObjectName(), ObjectInfo: objectInfo, }); isDone { return } } - if err := revisionIterator.Err(); err != nil { + if err := it.Err(); err != nil { sendCatfileInfoResult(ctx, resultChan, CatfileInfoResult{err: err}) return } diff --git a/internal/git/gitpipe/catfile_info_iterator.go b/internal/git/gitpipe/catfile_info_iterator.go index 54a75b5d9..13a83ccca 100644 --- a/internal/git/gitpipe/catfile_info_iterator.go +++ b/internal/git/gitpipe/catfile_info_iterator.go @@ -1,11 +1,10 @@ package gitpipe +import "gitlab.com/gitlab-org/gitaly/v14/internal/git" + // CatfileInfoIterator is an iterator returned by the Revlist function. type CatfileInfoIterator interface { - // Next iterates to the next item. Returns `false` in case there are no more results left. - Next() bool - // Err returns the first error that was encountered. - Err() error + ObjectIterator // Result returns the current item. Result() CatfileInfoResult } @@ -49,3 +48,11 @@ func (it *catfileInfoIterator) Err() error { func (it *catfileInfoIterator) Result() CatfileInfoResult { return it.result } + +func (it *catfileInfoIterator) ObjectID() git.ObjectID { + return it.result.ObjectInfo.Oid +} + +func (it *catfileInfoIterator) ObjectName() []byte { + return it.result.ObjectName +} diff --git a/internal/git/gitpipe/catfile_object.go b/internal/git/gitpipe/catfile_object.go index 4172dffdb..3a8c2d89a 100644 --- a/internal/git/gitpipe/catfile_object.go +++ b/internal/git/gitpipe/catfile_object.go @@ -32,7 +32,7 @@ type CatfileObjectResult struct { func CatfileObject( ctx context.Context, objectReader catfile.ObjectReader, - it CatfileInfoIterator, + it ObjectIterator, ) CatfileObjectIterator { resultChan := make(chan CatfileObjectResult) go func() { @@ -62,8 +62,6 @@ func CatfileObject( var objectDataReader *signallingReader for it.Next() { - catfileInfoResult := it.Result() - // We mustn't try to read another object before reading the previous object // has concluded. Given that this is not under our control but under the // control of the caller, we thus have to wait until the blocking reader has @@ -76,7 +74,7 @@ func CatfileObject( } } - object, err := objectReader.Object(ctx, catfileInfoResult.ObjectInfo.Oid.Revision()) + object, err := objectReader.Object(ctx, it.ObjectID().Revision()) if err != nil { sendResult(CatfileObjectResult{ err: fmt.Errorf("requesting object: %w", err), @@ -90,8 +88,8 @@ func CatfileObject( } if isDone := sendResult(CatfileObjectResult{ - ObjectName: catfileInfoResult.ObjectName, - ObjectInfo: catfileInfoResult.ObjectInfo, + ObjectName: it.ObjectName(), + ObjectInfo: &object.ObjectInfo, ObjectReader: objectDataReader, }); isDone { return diff --git a/internal/git/gitpipe/catfile_object_iterator.go b/internal/git/gitpipe/catfile_object_iterator.go index 372a94f3c..7f4a05622 100644 --- a/internal/git/gitpipe/catfile_object_iterator.go +++ b/internal/git/gitpipe/catfile_object_iterator.go @@ -1,11 +1,10 @@ package gitpipe +import "gitlab.com/gitlab-org/gitaly/v14/internal/git" + // CatfileObjectIterator is an iterator returned by the Revlist function. type CatfileObjectIterator interface { - // Next iterates to the next item. Returns `false` in case there are no more results left. - Next() bool - // Err returns the first error that was encountered. - Err() error + ObjectIterator // Result returns the current item. Result() CatfileObjectResult } @@ -49,3 +48,11 @@ func (it *catfileObjectIterator) Err() error { func (it *catfileObjectIterator) Result() CatfileObjectResult { return it.result } + +func (it *catfileObjectIterator) ObjectID() git.ObjectID { + return it.result.ObjectInfo.Oid +} + +func (it *catfileObjectIterator) ObjectName() []byte { + return it.result.ObjectName +} diff --git a/internal/git/gitpipe/object_iterator.go b/internal/git/gitpipe/object_iterator.go new file mode 100644 index 000000000..5628bc2c7 --- /dev/null +++ b/internal/git/gitpipe/object_iterator.go @@ -0,0 +1,19 @@ +package gitpipe + +import "gitlab.com/gitlab-org/gitaly/v14/internal/git" + +// ObjectIterator is a common interface that is shared across the pipeline steps that work with +// objects. +type ObjectIterator interface { + // Next iterates to the next item. Returns `false` in case there are no more results left, + // or if an error happened during iteration. The caller must call `Err()` after `Next()` has + // returned `false`. + Next() bool + // Err returns the first error that was encountered. + Err() error + // ObjectID returns the object ID of the current object. + ObjectID() git.ObjectID + // ObjectName returns the object name of the current object. This is a + // implementation-specific field and may not be set. + ObjectName() []byte +} diff --git a/internal/git/gitpipe/revision_iterator.go b/internal/git/gitpipe/revision_iterator.go index 828c0d965..8d949e648 100644 --- a/internal/git/gitpipe/revision_iterator.go +++ b/internal/git/gitpipe/revision_iterator.go @@ -1,11 +1,10 @@ package gitpipe +import "gitlab.com/gitlab-org/gitaly/v14/internal/git" + // RevisionIterator is an iterator returned by the Revlist function. type RevisionIterator interface { - // Next iterates to the next item. Returns `false` in case there are no more results left. - Next() bool - // Err returns the first error that was encountered. - Err() error + ObjectIterator // Result returns the current item. Result() RevisionResult } @@ -49,3 +48,11 @@ func (it *revisionIterator) Err() error { func (it *revisionIterator) Result() RevisionResult { return it.result } + +func (it *revisionIterator) ObjectID() git.ObjectID { + return it.result.OID +} + +func (it *revisionIterator) ObjectName() []byte { + return it.result.ObjectName +} |