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  }