github.com/q2/git-lfs@v0.5.1-0.20150410234700-03a0d4cec40e/lfs/util.go (about) 1 package lfs 2 3 import ( 4 "fmt" 5 "io" 6 "os" 7 "path/filepath" 8 ) 9 10 type CallbackReader struct { 11 C CopyCallback 12 TotalSize int64 13 ReadSize int64 14 io.Reader 15 } 16 17 type CopyCallback func(int64, int64) error 18 19 func (w *CallbackReader) Read(p []byte) (int, error) { 20 n, err := w.Reader.Read(p) 21 22 if n > 0 { 23 w.ReadSize += int64(n) 24 } 25 26 if err == nil && w.C != nil { 27 err = w.C(w.TotalSize, w.ReadSize) 28 } 29 30 return n, err 31 } 32 33 func CopyWithCallback(writer io.Writer, reader io.Reader, totalSize int64, cb CopyCallback) (int64, error) { 34 if cb == nil { 35 return io.Copy(writer, reader) 36 } 37 38 cbReader := &CallbackReader{ 39 C: cb, 40 TotalSize: totalSize, 41 Reader: reader, 42 } 43 return io.Copy(writer, cbReader) 44 } 45 46 func CopyCallbackFile(event, filename string, index, totalFiles int) (CopyCallback, *os.File, error) { 47 logPath := os.Getenv("GIT_LFS_PROGRESS") 48 if len(logPath) == 0 || len(filename) == 0 || len(event) == 0 { 49 return nil, nil, nil 50 } 51 52 if !filepath.IsAbs(logPath) { 53 return nil, nil, fmt.Errorf("GIT_LFS_PROGRESS must be an absolute path") 54 } 55 56 cbDir := filepath.Dir(logPath) 57 if err := os.MkdirAll(cbDir, 0755); err != nil { 58 return nil, nil, wrapProgressError(err, event, logPath) 59 } 60 61 file, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) 62 if err != nil { 63 return nil, file, wrapProgressError(err, event, logPath) 64 } 65 66 var prevWritten int64 67 68 cb := CopyCallback(func(total int64, written int64) error { 69 if written != prevWritten { 70 _, err := file.Write([]byte(fmt.Sprintf("%s %d/%d %d/%d %s\n", event, index, totalFiles, written, total, filename))) 71 file.Sync() 72 prevWritten = written 73 return wrapProgressError(err, event, logPath) 74 } 75 76 return nil 77 }) 78 79 return cb, file, nil 80 } 81 82 func wrapProgressError(err error, event, filename string) error { 83 if err == nil { 84 return nil 85 } 86 87 return fmt.Errorf("Error writing Git LFS %s progress to %s: %s", event, filename, err.Error()) 88 }