From 4abda3a60b31101d95d9c82a82691016b77a7ade Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carlos=20Mart=C3=ADn=20Nieto?= Date: Fri, 9 Aug 2013 18:22:26 +0200 Subject: [PATCH] reference: get references out of the iterator Allow getting references out of the iterator instead of just names. --- reference.go | 34 +++++++++++++++++++++++++++++++++- reference_test.go | 18 ++++++++++++++++++ 2 files changed, 51 insertions(+), 1 deletion(-) diff --git a/reference.go b/reference.go index 5aee276..cd8c42a 100644 --- a/reference.go +++ b/reference.go @@ -147,7 +147,7 @@ func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterato return iter, nil } -// Next retrieves the next reference name. If the iteration is over, +// NextName retrieves the next reference name. If the iteration is over, // the returned error is git.ErrIterOver func (v *ReferenceIterator) NextName() (string, error) { var ptr *C.char @@ -179,6 +179,38 @@ func (v *ReferenceIterator) NameIter() <-chan string { return ch } +// Next retrieves the next reference. If the iterationis over, the +// returned error is git.ErrIterOver +func (v *ReferenceIterator) Next() (*Reference, error) { + var ptr *C.git_reference + ret := C.git_reference_next(&ptr, v.ptr) + if ret == ITEROVER { + return nil, ErrIterOver + } + if ret < 0 { + return nil, LastError() + } + + return newReferenceFromC(ptr), nil +} + +// Create a channel from the iterator. You can use range on the +// returned channel to iterate over all the references names. The channel +// will be closed in case any error is found. +func (v *ReferenceIterator) Iter() <-chan *Reference { + ch := make(chan *Reference) + go func() { + defer close(ch) + name, err := v.Next() + for err == nil { + ch <- name + name, err = v.Next() + } + }() + + return ch +} + // Free the reference iterator func (v *ReferenceIterator) Free() { runtime.SetFinalizer(v, nil) diff --git a/reference_test.go b/reference_test.go index 77afaeb..eb9bb3f 100644 --- a/reference_test.go +++ b/reference_test.go @@ -112,6 +112,24 @@ func TestIterator(t *testing.T) { sort.Strings(list) compareStringList(t, expected, list) + // test the iterator for full refs, rather than just names + iter, err = repo.NewReferenceIterator() + checkFatal(t, err) + count := 0 + _, err = iter.Next() + for err == nil { + count++ + _, err = iter.Next() + } + if err != ErrIterOver { + t.Fatal("Iteration not over") + } + + if count != 4 { + t.Fatalf("Wrong number of references returned %v", count) + } + + // test the channel iteration list = []string{} iter, err = repo.NewReferenceIterator()