github.com/ahmet2mir/goreleaser@v0.180.3-0.20210927151101-8e5ee5a9b8c5/pkg/archive/tar/tar.go (about)

     1  // Package tar implements the Archive interface providing tar archiving.
     2  package tar
     3  
     4  import (
     5  	"archive/tar"
     6  	"io"
     7  	"os"
     8  
     9  	"github.com/goreleaser/goreleaser/pkg/config"
    10  )
    11  
    12  // Archive as tar.
    13  type Archive struct {
    14  	tw *tar.Writer
    15  }
    16  
    17  // New tar archive.
    18  func New(target io.Writer) Archive {
    19  	return Archive{
    20  		tw: tar.NewWriter(target),
    21  	}
    22  }
    23  
    24  // Close all closeables.
    25  func (a Archive) Close() error {
    26  	return a.tw.Close()
    27  }
    28  
    29  // Add file to the archive.
    30  func (a Archive) Add(f config.File) error {
    31  	file, err := os.Open(f.Source) // #nosec
    32  	if err != nil {
    33  		return err
    34  	}
    35  	defer file.Close()
    36  	info, err := os.Lstat(f.Source) // #nosec
    37  	if err != nil {
    38  		return err
    39  	}
    40  	var link string
    41  	if info.Mode()&os.ModeSymlink != 0 {
    42  		link, err = os.Readlink(f.Source) // #nosec
    43  		if err != nil {
    44  			return err
    45  		}
    46  	}
    47  	header, err := tar.FileInfoHeader(info, link)
    48  	if err != nil {
    49  		return err
    50  	}
    51  	header.Name = f.Destination
    52  	if !f.Info.MTime.IsZero() {
    53  		header.ModTime = f.Info.MTime
    54  	}
    55  	if f.Info.Mode != 0 {
    56  		header.Mode = int64(f.Info.Mode)
    57  	}
    58  	if f.Info.Owner != "" {
    59  		header.Uid = 0
    60  		header.Uname = f.Info.Owner
    61  	}
    62  	if f.Info.Group != "" {
    63  		header.Gid = 0
    64  		header.Gname = f.Info.Group
    65  	}
    66  	if err = a.tw.WriteHeader(header); err != nil {
    67  		return err
    68  	}
    69  	if info.IsDir() || info.Mode()&os.ModeSymlink != 0 {
    70  		return nil
    71  	}
    72  	_, err = io.Copy(a.tw, file)
    73  	return err
    74  }