golang.org/x/build@v0.0.0-20240506185731-218518f32b70/internal/task/buildrelease.go (about) 1 // Copyright 2022 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package task 6 7 import ( 8 "archive/tar" 9 "archive/zip" 10 "compress/gzip" 11 "io" 12 "path" 13 "strings" 14 ) 15 16 // ExtractFile copies the first file in tgz matching glob to dest. 17 func ExtractFile(tgz io.Reader, dest io.Writer, glob string) error { 18 zr, err := gzip.NewReader(tgz) 19 if err != nil { 20 return err 21 } 22 tr := tar.NewReader(zr) 23 for { 24 h, err := tr.Next() 25 if err == io.EOF { 26 return io.ErrUnexpectedEOF 27 } else if err != nil { 28 return err 29 } 30 if match, _ := path.Match(glob, h.Name); !h.FileInfo().IsDir() && match { 31 break 32 } 33 } 34 _, err = io.Copy(dest, tr) 35 return err 36 } 37 38 func ConvertZIPToTGZ(r io.ReaderAt, size int64, w io.Writer) error { 39 zr, err := zip.NewReader(r, size) 40 if err != nil { 41 return err 42 } 43 44 zw := gzip.NewWriter(w) 45 tw := tar.NewWriter(zw) 46 47 for _, f := range zr.File { 48 if strings.HasSuffix(f.Name, "/") { 49 continue 50 } 51 if err := tw.WriteHeader(&tar.Header{ 52 Name: f.Name, 53 Typeflag: tar.TypeReg, 54 Mode: 0o777, 55 Size: int64(f.UncompressedSize64), 56 57 AccessTime: f.Modified, 58 ChangeTime: f.Modified, 59 ModTime: f.Modified, 60 }); err != nil { 61 return err 62 } 63 content, err := f.Open() 64 if err != nil { 65 return err 66 } 67 if _, err := io.Copy(tw, content); err != nil { 68 return err 69 } 70 if err := content.Close(); err != nil { 71 return err 72 } 73 } 74 75 if err := tw.Close(); err != nil { 76 return err 77 } 78 return zw.Close() 79 }