github.com/nilium/gitlab-runner@v12.5.0+incompatible/helpers/archives/zip_create.go (about)

     1  package archives
     2  
     3  import (
     4  	"archive/zip"
     5  	"io"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	"github.com/sirupsen/logrus"
    11  )
    12  
    13  func createZipDirectoryEntry(archive *zip.Writer, fh *zip.FileHeader) error {
    14  	fh.Name += "/"
    15  	_, err := archive.CreateHeader(fh)
    16  	return err
    17  }
    18  
    19  func createZipSymlinkEntry(archive *zip.Writer, fh *zip.FileHeader) error {
    20  	fw, err := archive.CreateHeader(fh)
    21  	if err != nil {
    22  		return err
    23  	}
    24  
    25  	link, err := os.Readlink(fh.Name)
    26  	if err != nil {
    27  		return err
    28  	}
    29  
    30  	_, err = io.WriteString(fw, link)
    31  	return err
    32  }
    33  
    34  func createZipFileEntry(archive *zip.Writer, fh *zip.FileHeader) error {
    35  	fh.Method = zip.Deflate
    36  	fw, err := archive.CreateHeader(fh)
    37  	if err != nil {
    38  		return err
    39  	}
    40  
    41  	file, err := os.Open(fh.Name)
    42  	if err != nil {
    43  		return err
    44  	}
    45  
    46  	_, err = io.Copy(fw, file)
    47  	file.Close()
    48  	if err != nil {
    49  		return err
    50  	}
    51  	return nil
    52  }
    53  
    54  func createZipEntry(archive *zip.Writer, fileName string) error {
    55  	fi, err := os.Lstat(fileName)
    56  	if err != nil {
    57  		logrus.Warningln("File ignored:", err)
    58  		return nil
    59  	}
    60  
    61  	fh, err := zip.FileInfoHeader(fi)
    62  	if err != nil {
    63  		return err
    64  	}
    65  	fh.Name = fileName
    66  	fh.Extra = createZipExtra(fi)
    67  
    68  	switch fi.Mode() & os.ModeType {
    69  	case os.ModeDir:
    70  		return createZipDirectoryEntry(archive, fh)
    71  
    72  	case os.ModeSymlink:
    73  		return createZipSymlinkEntry(archive, fh)
    74  
    75  	case os.ModeNamedPipe, os.ModeSocket, os.ModeDevice:
    76  		// Ignore the files that of these types
    77  		logrus.Warningln("File ignored:", fileName)
    78  		return nil
    79  
    80  	default:
    81  		return createZipFileEntry(archive, fh)
    82  	}
    83  }
    84  
    85  func CreateZipArchive(w io.Writer, fileNames []string) error {
    86  	tracker := newPathErrorTracker()
    87  
    88  	archive := zip.NewWriter(w)
    89  	defer archive.Close()
    90  
    91  	for _, fileName := range fileNames {
    92  		if err := errorIfGitDirectory(fileName); tracker.actionable(err) {
    93  			printGitArchiveWarning("archive")
    94  		}
    95  
    96  		err := createZipEntry(archive, fileName)
    97  		if err != nil {
    98  			return err
    99  		}
   100  	}
   101  
   102  	return nil
   103  }
   104  
   105  func CreateZipFile(fileName string, fileNames []string) error {
   106  	// create directories to store archive
   107  	err := os.MkdirAll(filepath.Dir(fileName), 0700)
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	tempFile, err := ioutil.TempFile(filepath.Dir(fileName), "archive_")
   113  	if err != nil {
   114  		return err
   115  	}
   116  	defer tempFile.Close()
   117  	defer os.Remove(tempFile.Name())
   118  
   119  	logrus.Debugln("Temporary file:", tempFile.Name())
   120  	err = CreateZipArchive(tempFile, fileNames)
   121  	if err != nil {
   122  		return err
   123  	}
   124  	tempFile.Close()
   125  
   126  	err = os.Rename(tempFile.Name(), fileName)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	return nil
   132  }