commands,lfs: teach lfs.DecodeFrom to return an io.Reader

This commit is contained in:
Taylor Blau 2016-12-23 12:16:57 -07:00
parent 614a74f6c9
commit 6f54232890
4 changed files with 23 additions and 25 deletions

@ -1,7 +1,6 @@
package commands
import (
"bytes"
"fmt"
"io"
"os"
@ -29,14 +28,9 @@ var (
// were non-fatal, otherwise execution will halt and the process will be
// terminated by using the `commands.Panic()` func.
func smudge(to io.Writer, from io.Reader, filename string, skip bool, filter *filepathfilter.Filter) error {
pbuf, more, ptr, perr := lfs.DecodeFromHasMore(from)
ptr, pbuf, perr := lfs.DecodeFrom(from)
if perr != nil {
var r io.Reader = bytes.NewReader(pbuf)
if more {
r = io.MultiReader(r, from)
}
if _, err := io.Copy(to, r); err != nil {
if _, err := io.Copy(to, pbuf); err != nil {
return errors.Wrap(err, perr.Error())
}

@ -104,33 +104,32 @@ func DecodePointerFromFile(file string) (*Pointer, error) {
return DecodePointer(f)
}
func DecodePointer(reader io.Reader) (*Pointer, error) {
_, p, err := DecodeFrom(reader)
p, _, err := DecodeFrom(reader)
return p, err
}
func DecodeFrom(reader io.Reader) ([]byte, *Pointer, error) {
output, _, p, err := DecodeFromHasMore(reader)
return output, p, err
}
// DecodeFromHasMore decodes an *lfs.Pointer from the given io.Reader, "reader".
// DecodeFrom decodes an *lfs.Pointer from the given io.Reader, "reader".
// If the pointer encoded in the reader could successfully be read and decoded,
// it will be returned with a nil error.
//
// If the pointer could not be decoded, a buffer of the data read so far, along
// with whether or not there was more data not yet consumed will be returned
// instead.
func DecodeFromHasMore(reader io.Reader) ([]byte, bool, *Pointer, error) {
// If the pointer could not be decoded, an io.Reader containing the entire
// blob's data will be returned, along with a parse error.
func DecodeFrom(reader io.Reader) (*Pointer, io.Reader, error) {
buf := make([]byte, blobSizeCutoff)
written, rerr := reader.Read(buf)
output := buf[0:written]
var buffer io.Reader = bytes.NewReader(output)
if rerr != io.EOF {
buffer = io.MultiReader(buffer, reader)
}
if rerr != nil && rerr != io.EOF {
return output, true, nil, rerr
return nil, buffer, rerr
}
p, err := decodeKV(bytes.TrimSpace(output))
return output, rerr != io.EOF, p, err
return p, buffer, err
}
func verifyVersion(version string) error {

@ -5,6 +5,7 @@ import (
"crypto/sha256"
"encoding/hex"
"io"
"io/ioutil"
"os"
"github.com/git-lfs/git-lfs/config"
@ -76,8 +77,9 @@ func copyToTemp(reader io.Reader, fileSize int64, cb progress.CopyCallback) (oid
cb = nil
}
by, ptr, err := DecodeFrom(reader)
if err == nil && len(by) < 512 {
ptr, buf, err := DecodeFrom(reader)
by, rerr := ioutil.ReadAll(buf)
if rerr != nil || (err == nil && len(by) < 512) {
err = errors.NewCleanPointerError(ptr, by)
return
}

@ -3,6 +3,7 @@ package lfs
import (
"bufio"
"bytes"
"io/ioutil"
"reflect"
"strings"
"testing"
@ -168,11 +169,13 @@ size 12345`
}
func TestDecodeFromEmptyReader(t *testing.T) {
by, p, err := DecodeFrom(strings.NewReader(""))
p, buf, err := DecodeFrom(strings.NewReader(""))
by, rerr := ioutil.ReadAll(buf)
assert.Nil(t, rerr)
assert.EqualError(t, err, "Pointer file error: invalid header")
assert.Nil(t, p)
assert.Empty(t, string(by))
assert.Empty(t, by)
}
func TestDecodeInvalid(t *testing.T) {