git-lfs/lfs/pointer_clean.go
2016-08-18 15:24:11 -06:00

99 lines
2.0 KiB
Go

package lfs
import (
"bytes"
"crypto/sha256"
"encoding/hex"
"io"
"os"
"github.com/github/git-lfs/config"
"github.com/github/git-lfs/errors"
"github.com/github/git-lfs/progress"
"github.com/github/git-lfs/tools"
)
type cleanedAsset struct {
Filename string
*Pointer
}
func PointerClean(reader io.Reader, fileName string, fileSize int64, cb progress.CopyCallback) (*cleanedAsset, error) {
extensions, err := config.Config.SortedExtensions()
if err != nil {
return nil, err
}
var oid string
var size int64
var tmp *os.File
var exts []*PointerExtension
if len(extensions) > 0 {
request := &pipeRequest{"clean", reader, fileName, extensions}
var response pipeResponse
if response, err = pipeExtensions(request); err != nil {
return nil, err
}
oid = response.results[len(response.results)-1].oidOut
tmp = response.file
var stat os.FileInfo
if stat, err = os.Stat(tmp.Name()); err != nil {
return nil, err
}
size = stat.Size()
for _, result := range response.results {
if result.oidIn != result.oidOut {
ext := NewPointerExtension(result.name, len(exts), result.oidIn)
exts = append(exts, ext)
}
}
} else {
oid, size, tmp, err = copyToTemp(reader, fileSize, cb)
if err != nil {
return nil, err
}
}
pointer := NewPointer(oid, size, exts)
return &cleanedAsset{tmp.Name(), pointer}, err
}
func copyToTemp(reader io.Reader, fileSize int64, cb progress.CopyCallback) (oid string, size int64, tmp *os.File, err error) {
tmp, err = TempFile("")
if err != nil {
return
}
defer tmp.Close()
oidHash := sha256.New()
writer := io.MultiWriter(oidHash, tmp)
if fileSize == 0 {
cb = nil
}
by, ptr, err := DecodeFrom(reader)
if err == nil && len(by) < 512 {
err = errors.NewCleanPointerError(ptr, by)
return
}
multi := io.MultiReader(bytes.NewReader(by), reader)
size, err = tools.CopyWithCallback(writer, multi, fileSize, cb)
if err != nil {
return
}
oid = hex.EncodeToString(oidHash.Sum(nil))
return
}
func (a *cleanedAsset) Teardown() error {
return os.Remove(a.Filename)
}