15 type download struct {
23 func (d *download) Init(cfg *Config) {}
25 func (d *download) Children() []task {
29 func (d *download) ShortName() string {
33 func (d *download) String() string {
34 return fmt.Sprintf("Download %q from %q", d.Dest, d.URL)
37 func (d *download) Check() error {
38 fi, err := os.Stat(d.Dest)
42 if d.Size > 0 && fi.Size() != d.Size {
43 return fmt.Errorf("Size mismatch: %q is %d bytes, expected %d", d.Dest, fi.Size(), d.Size)
45 if d.Mode > 0 && fi.Mode() != d.Mode {
46 return fmt.Errorf("Mode mismatch: %q is %s, expected %s", d.Dest, fi.Mode(), d.Mode)
51 func (d *download) CanFix() bool {
55 func (d *download) Fix() error {
56 out, err := ioutil.TempFile(path.Dir(d.Dest), path.Base(d.Dest))
67 resp, err := http.Get(d.URL)
71 n, err := io.Copy(out, resp.Body)
77 if strings.HasSuffix(d.URL, ".zip") && !strings.HasSuffix(d.Dest, ".zip") {
78 r, err := zip.NewReader(out, n)
82 defer os.Remove(out.Name())
86 for _, f := range r.File {
87 if !strings.HasSuffix(d.Dest, "/"+f.Name) {
96 out, err = ioutil.TempFile(path.Dir(d.Dest), path.Base(d.Dest))
101 n, err = io.Copy(out, rc)
109 return fmt.Errorf("File not found in archive")
113 if d.Size > 0 && d.Size != n {
114 return fmt.Errorf("Size mismatch: got %d bytes, expected %d", n, d.Size)
115 } else if d.Size == 0 {
116 log.Printf("%s: size was %d", d, n)
118 if err = out.Close(); err != nil {
121 if err = os.Chmod(out.Name(), d.Mode); err != nil {
124 err = os.Rename(out.Name(), d.Dest)
126 // skip deferred os.Remove(out.Name())