github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/pkg/archive/zip/zip.go (about) 1 // Package zip implements the Archive interface providing zip archiving 2 // and compression. 3 package zip 4 5 import ( 6 "archive/zip" 7 "compress/flate" 8 "io" 9 "os" 10 11 "github.com/goreleaser/goreleaser/pkg/config" 12 ) 13 14 // Archive zip struct. 15 type Archive struct { 16 z *zip.Writer 17 } 18 19 // New zip archive. 20 func New(target io.Writer) Archive { 21 compressor := zip.NewWriter(target) 22 compressor.RegisterCompressor(zip.Deflate, func(out io.Writer) (io.WriteCloser, error) { 23 return flate.NewWriter(out, flate.BestCompression) 24 }) 25 return Archive{ 26 z: compressor, 27 } 28 } 29 30 // Close all closeables. 31 func (a Archive) Close() error { 32 return a.z.Close() 33 } 34 35 // Add a file to the zip archive. 36 func (a Archive) Add(f config.File) error { 37 file, err := os.Open(f.Source) // #nosec 38 if err != nil { 39 return err 40 } 41 defer file.Close() 42 info, err := os.Lstat(f.Source) // #nosec 43 if err != nil { 44 return err 45 } 46 if info.IsDir() { 47 return err 48 } 49 header, err := zip.FileInfoHeader(info) 50 if err != nil { 51 return err 52 } 53 header.Name = f.Destination 54 header.Method = zip.Deflate 55 if !f.Info.MTime.IsZero() { 56 header.Modified = f.Info.MTime 57 } 58 if f.Info.Mode != 0 { 59 header.SetMode(f.Info.Mode) 60 } 61 w, err := a.z.CreateHeader(header) 62 if err != nil { 63 return err 64 } 65 _, err = io.Copy(w, file) 66 return err 67 } 68 69 // TODO: test fileinfo stuff