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  }