package progress import ( "fmt" "os" "path/filepath" ) // progressLogger provides a wrapper around an os.File that can either // write to the file or ignore all writes completely. type progressLogger struct { writeData bool log *os.File } // Write will write to the file and perform a Sync() if writing succeeds. func (l *progressLogger) Write(b []byte) error { if l.writeData { if _, err := l.log.Write(b); err != nil { return err } return l.log.Sync() } return nil } // Close will call Close() on the underlying file func (l *progressLogger) Close() error { if l.log != nil { return l.log.Close() } return nil } // Shutdown will cause the logger to ignore any further writes. It should // be used when writing causes an error. func (l *progressLogger) Shutdown() { l.writeData = false } // newProgressLogger creates a progressLogger with a log file path. // If a log file is able to be created, the logger will write to the file. If // there is an err creating the file, the logger will ignore all writes. func newProgressLogger(logPath string) (*progressLogger, error) { if len(logPath) == 0 { return &progressLogger{}, nil } if !filepath.IsAbs(logPath) { return &progressLogger{}, fmt.Errorf("GIT_LFS_PROGRESS must be an absolute path") } cbDir := filepath.Dir(logPath) if err := os.MkdirAll(cbDir, 0755); err != nil { return &progressLogger{}, err } file, err := os.OpenFile(logPath, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666) if err != nil { return &progressLogger{}, err } return &progressLogger{true, file}, nil }