NewBatchObjectIter returns a `*BatchObjectIterator` and an `io.WriteCloser`. The iterator iterates over objects whose names are fed into the `io.WriteCloser`, one per line. The `io.WriteCloser` should normally be closed and the iterator's output drained before `Close()` is called.
(ctx context.Context)
| 31 | // `io.WriteCloser` should normally be closed and the iterator's |
| 32 | // output drained before `Close()` is called. |
| 33 | func (repo *Repository) NewBatchObjectIter(ctx context.Context) (*BatchObjectIter, error) { |
| 34 | iter := BatchObjectIter{ |
| 35 | ctx: ctx, |
| 36 | p: pipe.New(), |
| 37 | oidCh: make(chan OID), |
| 38 | objCh: make(chan ObjectRecord), |
| 39 | errCh: make(chan error), |
| 40 | } |
| 41 | |
| 42 | iter.p.Add( |
| 43 | // Read OIDs from `iter.oidCh` and write them to `git |
| 44 | // cat-file`: |
| 45 | pipe.Function( |
| 46 | "request-objects", |
| 47 | func(ctx context.Context, _ pipe.Env, _ io.Reader, stdout io.Writer) error { |
| 48 | out := bufio.NewWriter(stdout) |
| 49 | |
| 50 | for { |
| 51 | select { |
| 52 | case oid, ok := <-iter.oidCh: |
| 53 | if !ok { |
| 54 | return out.Flush() |
| 55 | } |
| 56 | if _, err := fmt.Fprintln(out, oid.String()); err != nil { |
| 57 | return fmt.Errorf("writing to 'git cat-file': %w", err) |
| 58 | } |
| 59 | case <-ctx.Done(): |
| 60 | return ctx.Err() |
| 61 | } |
| 62 | } |
| 63 | }, |
| 64 | ), |
| 65 | |
| 66 | // Read OIDs from `stdin` and output a header line followed by |
| 67 | // the contents of the corresponding Git objects: |
| 68 | pipe.CommandStage( |
| 69 | "git-cat-file", |
| 70 | repo.GitCommand("cat-file", "--batch", "--buffer"), |
| 71 | ), |
| 72 | |
| 73 | // Parse the object headers and read the object contents, and |
| 74 | // shove both into `objCh`: |
| 75 | pipe.Function( |
| 76 | "object-reader", |
| 77 | func(ctx context.Context, _ pipe.Env, stdin io.Reader, _ io.Writer) error { |
| 78 | defer close(iter.objCh) |
| 79 | |
| 80 | f := bufio.NewReader(stdin) |
| 81 | |
| 82 | for { |
| 83 | header, err := f.ReadString('\n') |
| 84 | if err != nil { |
| 85 | if err == io.EOF { |
| 86 | return nil |
| 87 | } |
| 88 | return fmt.Errorf("reading from 'git cat-file': %w", err) |
| 89 | } |
| 90 | batchHeader, err := ParseBatchHeader("", header) |
no test coverage detected