github.com/ssube/gitlab-ci-multi-runner@v1.2.1-0.20160607142738-b8d1285632e6/helpers/archives/zip_extract.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 extractZipDirectoryEntry(file *zip.File) (err error) { 14 err = os.Mkdir(file.Name, file.Mode().Perm()) 15 16 // The error that directory does exists is not a error for us 17 if os.IsExist(err) { 18 err = nil 19 } 20 return 21 } 22 23 func extractZipSymlinkEntry(file *zip.File) (err error) { 24 var data []byte 25 in, err := file.Open() 26 if err != nil { 27 return err 28 } 29 defer in.Close() 30 31 data, err = ioutil.ReadAll(in) 32 if err != nil { 33 return err 34 } 35 36 // Remove symlink before creating a new one, otherwise we can error that file does exist 37 os.Remove(file.Name) 38 err = os.Symlink(string(data), file.Name) 39 return 40 } 41 42 func extractZipFileEntry(file *zip.File) (err error) { 43 var out *os.File 44 in, err := file.Open() 45 if err != nil { 46 return err 47 } 48 defer in.Close() 49 50 // Remove file before creating a new one, otherwise we can error that file does exist 51 os.Remove(file.Name) 52 out, err = os.OpenFile(file.Name, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, file.Mode().Perm()) 53 if err != nil { 54 return err 55 } 56 defer out.Close() 57 _, err = io.Copy(out, in) 58 59 return 60 } 61 62 func extractZipFile(file *zip.File) (err error) { 63 // Create all parents to extract the file 64 os.MkdirAll(filepath.Dir(file.Name), 0777) 65 66 switch file.Mode() & os.ModeType { 67 case os.ModeDir: 68 err = extractZipDirectoryEntry(file) 69 70 case os.ModeSymlink: 71 err = extractZipSymlinkEntry(file) 72 73 case os.ModeNamedPipe, os.ModeSocket, os.ModeDevice: 74 // Ignore the files that of these types 75 logrus.Warningln("File ignored: %q", file.Name) 76 77 default: 78 err = extractZipFileEntry(file) 79 } 80 return 81 } 82 83 func ExtractZipArchive(archive *zip.Reader) error { 84 for _, file := range archive.File { 85 if err := extractZipFile(file); err != nil { 86 logrus.Warningf("%s: %s", file.Name, err) 87 } 88 } 89 90 for _, file := range archive.File { 91 // Update file permissions 92 if err := os.Chmod(file.Name, file.Mode().Perm()); err != nil { 93 logrus.Warningf("%s: %s", file.Name, err) 94 } 95 96 // Process zip metadata 97 if err := processZipExtra(&file.FileHeader); err != nil { 98 logrus.Warningf("%s: %s", file.Name, err) 99 } 100 } 101 return nil 102 } 103 104 func ExtractZipFile(fileName string) error { 105 archive, err := zip.OpenReader(fileName) 106 if err != nil { 107 return err 108 } 109 defer archive.Close() 110 111 return ExtractZipArchive(&archive.Reader) 112 }