kubesphere.io/s2irun@v3.2.1+incompatible/pkg/scm/downloaders/binary/download.go (about) 1 package binary 2 3 import ( 4 "github.com/kubesphere/s2irun/pkg/api" 5 "github.com/kubesphere/s2irun/pkg/api/constants" 6 "github.com/kubesphere/s2irun/pkg/scm/git" 7 "github.com/kubesphere/s2irun/pkg/utils/bytefmt" 8 "github.com/kubesphere/s2irun/pkg/utils/fs" 9 utilglog "github.com/kubesphere/s2irun/pkg/utils/glog" 10 "io" 11 "net/http" 12 "path/filepath" 13 "strconv" 14 "strings" 15 ) 16 17 var glog = utilglog.StderrLog 18 19 // File represents a simplest possible Downloader implementation where the 20 // sources are just copied from local directory. 21 type File struct { 22 fs.FileSystem 23 } 24 25 // Download download sources from a http link into the working directory. 26 // Caller guarantees that config.Source.IsLocal() is true. 27 func (f *File) Download(config *api.Config) (*git.SourceInfo, error) { 28 _, filename := filepath.Split(config.Source.String()) 29 config.WorkingSourceDir = filepath.Join(config.WorkingDir, constants.Source) 30 binaryPath := filepath.Join(config.WorkingSourceDir, filename) 31 glog.V(0).Infof("Start Download Binary %s", filename) 32 resp, err := http.Get(config.Source.String()) 33 if err != nil { 34 return nil, err 35 } 36 defer resp.Body.Close() 37 out, err := f.Create(binaryPath) 38 if err != nil { 39 return nil, err 40 } 41 42 defer out.Close() 43 44 strsize := resp.Header.Get("Content-Length") 45 size, _ := strconv.ParseUint(strsize, 10, 64) 46 47 counter := &WriteCounter{Size: size} 48 _, err = io.Copy(out, io.TeeReader(resp.Body, counter)) 49 glog.V(0).Infof("Finish Download Binary %s", filename) 50 glog.V(0).Infof("Binary size %s", bytefmt.ByteSize(counter.Total)) 51 return &git.SourceInfo{ 52 Location: config.Source.String(), 53 ContextDir: config.ContextDir, 54 BinaryName: filename, 55 BinarySize: counter.Total, 56 }, nil 57 } 58 59 // write cycle. 60 type WriteCounter struct { 61 Total uint64 62 Size uint64 63 } 64 65 func (wc *WriteCounter) Write(p []byte) (int, error) { 66 n := len(p) 67 wc.Total += uint64(n) 68 wc.PrintProgress() 69 return n, nil 70 } 71 72 func (wc WriteCounter) PrintProgress() { 73 // Clear the line by using a character return to go back to the start and remove 74 // the remaining characters by filling it with spaces 75 glog.V(0).Infof("\r%s", strings.Repeat(" ", 35)) 76 77 // Return again and print current status of download 78 // We use the humanize package to print the bytes in a meaningful way (e.g. 10 MB) 79 if wc.Size > 0 { 80 glog.V(0).Infof("\rDownloading... %s/%s", bytefmt.ByteSize(wc.Total), bytefmt.ByteSize(wc.Size)) 81 } else { 82 glog.V(0).Infof("\rDownloading... %s complete", bytefmt.ByteSize(wc.Total)) 83 } 84 85 }