github.com/vtorhonen/terraform@v0.9.0-beta2.0.20170307220345-5d894e4ffda7/builtin/providers/archive/zip_archiver.go (about) 1 package archive 2 3 import ( 4 "archive/zip" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "sort" 10 ) 11 12 type ZipArchiver struct { 13 filepath string 14 filewriter *os.File 15 writer *zip.Writer 16 } 17 18 func NewZipArchiver(filepath string) Archiver { 19 return &ZipArchiver{ 20 filepath: filepath, 21 } 22 } 23 24 func (a *ZipArchiver) ArchiveContent(content []byte, infilename string) error { 25 if err := a.open(); err != nil { 26 return err 27 } 28 defer a.close() 29 30 f, err := a.writer.Create(infilename) 31 if err != nil { 32 return err 33 } 34 35 _, err = f.Write(content) 36 return err 37 } 38 39 func (a *ZipArchiver) ArchiveFile(infilename string) error { 40 fi, err := assertValidFile(infilename) 41 if err != nil { 42 return err 43 } 44 45 content, err := ioutil.ReadFile(infilename) 46 if err != nil { 47 return err 48 } 49 50 return a.ArchiveContent(content, fi.Name()) 51 } 52 53 func (a *ZipArchiver) ArchiveDir(indirname string) error { 54 _, err := assertValidDir(indirname) 55 if err != nil { 56 return err 57 } 58 59 if err := a.open(); err != nil { 60 return err 61 } 62 defer a.close() 63 64 return filepath.Walk(indirname, func(path string, info os.FileInfo, err error) error { 65 if info.IsDir() { 66 return nil 67 } 68 if err != nil { 69 return err 70 } 71 relname, err := filepath.Rel(indirname, path) 72 if err != nil { 73 return fmt.Errorf("error relativizing file for archival: %s", err) 74 } 75 f, err := a.writer.Create(relname) 76 if err != nil { 77 return fmt.Errorf("error creating file inside archive: %s", err) 78 } 79 content, err := ioutil.ReadFile(path) 80 if err != nil { 81 return fmt.Errorf("error reading file for archival: %s", err) 82 } 83 _, err = f.Write(content) 84 return err 85 }) 86 87 } 88 89 func (a *ZipArchiver) ArchiveMultiple(content map[string][]byte) error { 90 if err := a.open(); err != nil { 91 return err 92 } 93 defer a.close() 94 95 // Ensure files are processed in the same order so hashes don't change 96 keys := make([]string, len(content)) 97 i := 0 98 for k := range content { 99 keys[i] = k 100 i++ 101 } 102 sort.Strings(keys) 103 104 for _, filename := range keys { 105 f, err := a.writer.Create(filename) 106 if err != nil { 107 return err 108 } 109 _, err = f.Write(content[filename]) 110 if err != nil { 111 return err 112 } 113 } 114 return nil 115 } 116 117 func (a *ZipArchiver) open() error { 118 f, err := os.Create(a.filepath) 119 if err != nil { 120 return err 121 } 122 a.filewriter = f 123 a.writer = zip.NewWriter(f) 124 return nil 125 } 126 127 func (a *ZipArchiver) close() { 128 if a.writer != nil { 129 a.writer.Close() 130 a.writer = nil 131 } 132 if a.filewriter != nil { 133 a.filewriter.Close() 134 a.filewriter = nil 135 } 136 }