internal/build: refactor download a bit

This commit is contained in:
Felix Lange 2019-11-15 15:15:32 +01:00
parent 66248ff3ef
commit 752a3dc029

View file

@ -82,51 +82,68 @@ func (db *ChecksumDB) DownloadFile(url, dstPath string) error {
fmt.Printf("%s is stale\n", dstPath) fmt.Printf("%s is stale\n", dstPath)
fmt.Printf("downloading from %s\n", url) fmt.Printf("downloading from %s\n", url)
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
return err
}
resp, err := http.Get(url) resp, err := http.Get(url)
if err != nil || resp.StatusCode != http.StatusOK { if err != nil || resp.StatusCode != http.StatusOK {
return fmt.Errorf("download error: code %d, err %v", resp.StatusCode, err) return fmt.Errorf("download error: code %d, err %v", resp.StatusCode, err)
} }
defer resp.Body.Close() defer resp.Body.Close()
if err := os.MkdirAll(filepath.Dir(dstPath), 0755); err != nil {
return err
}
fd, err := os.OpenFile(dstPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644) fd, err := os.OpenFile(dstPath, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0644)
if err != nil { if err != nil {
return err return err
} }
dst := bufio.NewWriter(io.MultiWriter(fd, &dots{length: resp.ContentLength})) dst := newDownloadWriter(fd, resp.ContentLength)
_, copyErr := io.Copy(dst, resp.Body) _, err = io.Copy(dst, resp.Body)
flushErr := dst.Flush() dst.Close()
fd.Close() if err != nil {
if copyErr != nil { return err
return copyErr
} else if flushErr != nil {
return flushErr
} }
return db.Verify(dstPath) return db.Verify(dstPath)
} }
type dots struct { type downloadWriter struct {
c int64 file *os.File
length int64 dstBuf *bufio.Writer
size int64
written int64
lastpct int64 lastpct int64
} }
func (d *dots) Write(buf []byte) (int, error) { func newDownloadWriter(dst *os.File, size int64) *downloadWriter {
d.c += int64(len(buf)) return &downloadWriter{
pct := d.c * 10 / d.length * 10 file: dst,
if pct != d.lastpct { dstBuf: bufio.NewWriter(dst),
if d.lastpct != 0 { size: size,
}
}
func (w *downloadWriter) Write(buf []byte) (int, error) {
n, err := w.dstBuf.Write(buf)
// Report progress.
w.written += int64(n)
pct := w.written * 10 / w.size * 10
if pct != w.lastpct {
if w.lastpct != 0 {
fmt.Print("...") fmt.Print("...")
} }
fmt.Print(pct, "%") fmt.Print(pct, "%")
d.lastpct = pct w.lastpct = pct
} }
if pct == 100 { return n, err
fmt.Println() }
}
return len(buf), nil func (w *downloadWriter) Close() error {
if w.lastpct > 0 {
fmt.Println() // Finish the progress line.
}
flushErr := w.dstBuf.Flush()
closeErr := w.file.Close()
if flushErr != nil {
return flushErr
}
return closeErr
} }