15 type download struct {
23 func (d *download) String() string {
24 return fmt.Sprintf("Download %q from %q", d.Dest, d.URL)
27 func (d *download) Check() error {
28 fi, err := os.Stat(d.Dest)
32 if d.Size > 0 && fi.Size() != d.Size {
33 return fmt.Errorf("Size mismatch: %q is %d bytes, expected %d", d.Dest, fi.Size(), d.Size)
35 if d.Mode > 0 && fi.Mode() != d.Mode {
36 return fmt.Errorf("Mode mismatch: %q is %s, expected %s", d.Dest, fi.Mode(), d.Mode)
41 func (d *download) CanFix() bool {
45 func (d *download) Fix() error {
46 out, err := ioutil.TempFile(path.Dir(d.Dest), path.Base(d.Dest))
57 resp, err := http.Get(d.URL)
61 n, err := io.Copy(out, resp.Body)
67 if strings.HasSuffix(d.URL, ".zip") && !strings.HasSuffix(d.Dest, ".zip") {
68 r, err := zip.NewReader(out, n)
72 defer os.Remove(out.Name())
76 for _, f := range r.File {
77 if !strings.HasSuffix(d.Dest, "/"+f.Name) {
86 out, err = ioutil.TempFile(path.Dir(d.Dest), path.Base(d.Dest))
91 n, err = io.Copy(out, rc)
99 return fmt.Errorf("File not found in archive")
103 if d.Size > 0 && d.Size != n {
104 return fmt.Errorf("Size mismatch: got %d bytes, expected %d", n, d.Size)
105 } else if d.Size == 0 {
106 log.Printf("%s: size was %d", d, n)
108 if err = out.Close(); err != nil {
111 if err = os.Chmod(out.Name(), d.Mode); err != nil {
114 err = os.Rename(out.Name(), d.Dest)
116 // skip deferred os.Remove(out.Name())