git-lfs/lfs/util.go

89 lines
1.9 KiB
Go
Raw Permalink Normal View History

2015-03-19 19:30:55 +00:00
package lfs
2014-08-06 22:04:34 +00:00
import (
"fmt"
2014-08-06 22:04:34 +00:00
"io"
"os"
"path/filepath"
2014-08-06 22:04:34 +00:00
)
type CallbackReader struct {
C CopyCallback
TotalSize int64
ReadSize int64
io.Reader
2014-08-06 22:04:34 +00:00
}
2015-06-17 08:59:15 +00:00
type CopyCallback func(totalSize int64, readSoFar int64, readSinceLast int) error
2014-08-07 14:53:13 +00:00
func (w *CallbackReader) Read(p []byte) (int, error) {
n, err := w.Reader.Read(p)
2014-08-06 22:04:34 +00:00
if n > 0 {
w.ReadSize += int64(n)
2014-08-06 22:04:34 +00:00
}
if err == nil && w.C != nil {
err = w.C(w.TotalSize, w.ReadSize, n)
2014-08-06 22:04:34 +00:00
}
return n, err
}
2014-08-07 14:53:13 +00:00
func CopyWithCallback(writer io.Writer, reader io.Reader, totalSize int64, cb CopyCallback) (int64, error) {
if cb == nil {
return io.Copy(writer, reader)
}
cbReader := &CallbackReader{
2014-08-06 22:04:34 +00:00
C: cb,
TotalSize: totalSize,
Reader: reader,
2014-08-06 22:04:34 +00:00
}
return io.Copy(writer, cbReader)
2014-08-06 22:04:34 +00:00
}
func CopyCallbackFile(event, filename string, index, totalFiles int) (CopyCallback, *os.File, error) {
logPath := Config.Getenv("GIT_LFS_PROGRESS")
if len(logPath) == 0 || len(filename) == 0 || len(event) == 0 {
return nil, nil, nil
}
if !filepath.IsAbs(logPath) {
2015-03-19 19:30:55 +00:00
return nil, nil, fmt.Errorf("GIT_LFS_PROGRESS must be an absolute path")
}
cbDir := filepath.Dir(logPath)
if err := os.MkdirAll(cbDir, 0755); err != nil {
return nil, nil, wrapProgressError(err, event, logPath)
}
file, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
if err != nil {
return nil, file, wrapProgressError(err, event, logPath)
}
var prevWritten int64
cb := CopyCallback(func(total int64, written int64, current int) error {
if written != prevWritten {
_, err := file.Write([]byte(fmt.Sprintf("%s %d/%d %d/%d %s\n", event, index, totalFiles, written, total, filename)))
file.Sync()
prevWritten = written
return wrapProgressError(err, event, logPath)
}
return nil
})
return cb, file, nil
}
func wrapProgressError(err error, event, filename string) error {
if err != nil {
return fmt.Errorf("Error writing Git LFS %s progress to %s: %s", event, filename, err.Error())
}
return nil
}