2
2
// Use of this source code is governed by a BSD-style
3
3
// license that can be found in the LICENSE file.
4
4
5
- // TODO(adg): put windows release in a zip file
6
-
7
5
// Command release builds a Go release.
8
6
package main
9
7
10
8
import (
11
9
"archive/tar"
10
+ "archive/zip"
12
11
"bytes"
13
12
"compress/gzip"
14
13
"flag"
45
44
46
45
var coordClient * buildlet.CoordinatorClient
47
46
47
+ const releaselet = "releaselet.go"
48
+
48
49
func main () {
49
50
flag .Parse ()
50
51
@@ -55,6 +56,10 @@ func main() {
55
56
return
56
57
}
57
58
59
+ if _ , err := os .Stat (releaselet ); err != nil {
60
+ log .Fatalf ("couldn't locate %q: %v" , releaselet , err )
61
+ }
62
+
58
63
if * rev == "" {
59
64
log .Fatal ("must specify -rev flag" )
60
65
}
@@ -355,7 +360,6 @@ func (b *Build) make() error {
355
360
356
361
b .logf ("Pushing and running releaselet." )
357
362
// TODO(adg): locate releaselet.go in GOPATH
358
- const releaselet = "releaselet.go"
359
363
f , err := os .Open (releaselet )
360
364
if err != nil {
361
365
return err
@@ -393,6 +397,9 @@ func (b *Build) make() error {
393
397
return err
394
398
}
395
399
400
+ if b .OS == "windows" {
401
+ return b .fetchZip (client )
402
+ }
396
403
return b .fetchTarball (client )
397
404
}
398
405
@@ -406,6 +413,79 @@ func (b *Build) fetchTarball(client *buildlet.Client) error {
406
413
return b .writeFile (filename , tgz )
407
414
}
408
415
416
+ func (b * Build ) fetchZip (client * buildlet.Client ) error {
417
+ b .logf ("Downloading tarball and re-compressing as zip." )
418
+
419
+ tgz , err := client .GetTar ("." )
420
+ if err != nil {
421
+ return err
422
+ }
423
+ defer tgz .Close ()
424
+
425
+ filename := * version + "." + b .String () + ".zip"
426
+ f , err := os .Create (filename )
427
+ if err != nil {
428
+ return err
429
+ }
430
+ if err := tgzToZip (f , tgz ); err != nil {
431
+ f .Close ()
432
+ return err
433
+ }
434
+ if err := f .Close (); err != nil {
435
+ return err
436
+ }
437
+
438
+ b .logf ("Wrote %q." , filename )
439
+ return nil
440
+ }
441
+
442
+ func tgzToZip (w io.Writer , r io.Reader ) error {
443
+ zr , err := gzip .NewReader (r )
444
+ if err != nil {
445
+ return err
446
+ }
447
+ tr := tar .NewReader (zr )
448
+
449
+ zw := zip .NewWriter (w )
450
+ for {
451
+ th , err := tr .Next ()
452
+ if err == io .EOF {
453
+ break
454
+ }
455
+ if err != nil {
456
+ return err
457
+ }
458
+ fi := th .FileInfo ()
459
+ zh , err := zip .FileInfoHeader (fi )
460
+ if err != nil {
461
+ return err
462
+ }
463
+ zh .Name = th .Name // for the full path
464
+ switch strings .ToLower (path .Ext (zh .Name )) {
465
+ case ".jpg" , ".jpeg" , ".png" , ".gif" :
466
+ // Don't re-compress already compressed files.
467
+ zh .Method = zip .Store
468
+ default :
469
+ zh .Method = zip .Deflate
470
+ }
471
+ if fi .IsDir () {
472
+ zh .Name += "/" // zip prefers a trailing slash
473
+ zh .Method = zip .Store
474
+ }
475
+ w , err := zw .CreateHeader (zh )
476
+ if err != nil {
477
+ return err
478
+ }
479
+ if fi .IsDir () {
480
+ continue
481
+ }
482
+ if _ , err := io .Copy (w , tr ); err != nil {
483
+ return err
484
+ }
485
+ }
486
+ return zw .Close ()
487
+ }
488
+
409
489
// fetchFile fetches the specified directory from the given buildlet, and
410
490
// writes the first file it finds in that directory to dest.
411
491
func (b * Build ) fetchFile (client * buildlet.Client , dest , dir string ) error {
0 commit comments